strafe_type/
model_matrix.rs

1use std::fmt::{Display, Formatter, Result as FmtResult};
2
3use nalgebra::DMatrix;
4use polars::{datatypes::DataType, frame::DataFrame};
5
6use crate::display_table::DisplayTable;
7
8#[derive(Clone, Debug)]
9pub struct ModelMatrix {
10    data: ModelMatrixData,
11    schema: Vec<ModelMatrixSchema>,
12}
13
14#[derive(Clone, Debug)]
15pub enum ModelMatrixData {
16    Vec {
17        name: String,
18        data: Vec<f64>,
19    },
20    Matrix {
21        names: Vec<String>,
22        data: DMatrix<f64>,
23    },
24    DataFrame(DataFrame),
25}
26
27#[derive(Copy, Clone, Debug, PartialEq, Eq)]
28pub enum ModelMatrixSchema {
29    Level,
30    Factor,
31    Value,
32    RowName,
33}
34
35fn write_table_bars(
36    column_widths: &[usize],
37    formatter: &mut Formatter,
38    left_bar: &str,
39    middle_blank: &str,
40    middle_bar: &str,
41    right_bar: &str,
42) -> FmtResult {
43    write!(formatter, "{left_bar}")?;
44    for (index, &len) in column_widths.iter().enumerate() {
45        if len > 0 {
46            for _ in 0..len + 2 {
47                write!(formatter, "{middle_blank}")?;
48            }
49            if index != column_widths.len() - 1 {
50                write!(formatter, "{middle_bar}")?;
51            }
52        }
53    }
54    writeln!(formatter, "{right_bar}")?;
55
56    Ok(())
57}
58
59fn write_data(
60    column_widths: &[usize],
61    formatter: &mut Formatter,
62    bar: &str,
63    row_names: &[String],
64    data: &Vec<Vec<String>>,
65) -> FmtResult {
66    for (row_index, row) in data.into_iter().enumerate() {
67        for (column_index, value) in row.iter().enumerate() {
68            write!(formatter, "{bar} ")?;
69            let column_index = if !row_names.is_empty() && column_index == 0 {
70                row_names[row_index].fmt(formatter)?;
71                for _ in 0..column_widths[column_index] - row_names[row_index].len() {
72                    write!(formatter, " ")?;
73                }
74                write!(formatter, " {bar} ")?;
75                value.fmt(formatter)?;
76                column_index + 1
77            } else {
78                value.fmt(formatter)?;
79                if !row_names.is_empty() {
80                    column_index + 1
81                } else {
82                    column_index
83                }
84            };
85            if column_widths[column_index] > value.to_string().len() {
86                for _ in 0..column_widths[column_index] - value.to_string().len() {
87                    write!(formatter, " ")?;
88                }
89            }
90            write!(formatter, " ")?;
91        }
92        writeln!(formatter, "{bar}")?;
93    }
94
95    Ok(())
96}
97
98fn as_factor<T: PartialOrd + PartialEq + ToString + Clone + Display>(
99    name: &str,
100    v: &[T],
101) -> (Vec<String>, DMatrix<f64>) {
102    let mut ret_names = Vec::new();
103    let mut ret_matrix = DMatrix::<f64>::zeros(v.len(), 0);
104
105    let mut unique_c = v.to_vec();
106    unique_c.sort_by(|u_c1, u_c2| u_c1.partial_cmp(u_c2).unwrap());
107    unique_c = unique_c.into_iter().fold(Vec::new(), |mut acc, v| {
108        if let Some(a_last) = acc.last() {
109            if a_last == &v {
110                acc
111            } else {
112                acc.push(v);
113                acc
114            }
115        } else {
116            acc.push(v);
117            acc
118        }
119    });
120    unique_c.sort_by(|a, b| a.partial_cmp(b).unwrap());
121
122    for j in 0..unique_c.len() {
123        ret_matrix = ret_matrix.insert_column(j, 0.0);
124        ret_names.push(format!("{} ({})", name, unique_c[j]));
125    }
126
127    for (j, c_j) in v.iter().enumerate() {
128        let column_index = unique_c
129            .binary_search_by(|a| a.partial_cmp(c_j).unwrap())
130            .unwrap();
131        ret_matrix[(j, column_index)] = 1.0;
132    }
133
134    (ret_names, ret_matrix)
135}
136
137fn as_level<T: PartialOrd + PartialEq + ToString + Clone>(v: &[T]) -> DMatrix<f64> {
138    let mut ret = DMatrix::<f64>::zeros(v.len(), 1);
139
140    let mut unique_c = v.to_vec();
141    unique_c.sort_by(|u_c1, u_c2| u_c1.partial_cmp(u_c2).unwrap());
142    unique_c = unique_c.into_iter().fold(Vec::new(), |mut acc, v| {
143        if let Some(a_last) = acc.last() {
144            if a_last == &v {
145                acc
146            } else {
147                acc.push(v);
148                acc
149            }
150        } else {
151            acc.push(v);
152            acc
153        }
154    });
155    unique_c.sort_by(|a, b| a.partial_cmp(b).unwrap());
156
157    for (i, c_t) in v.iter().enumerate() {
158        let index = unique_c
159            .binary_search_by(|u_c| u_c.partial_cmp(c_t).unwrap())
160            .unwrap();
161        ret[(i, 0)] = index as f64 + 1.0;
162    }
163
164    ret
165}
166
167impl ModelMatrix {
168    pub fn matrix(&self) -> DMatrix<f64> {
169        match &self.data {
170            ModelMatrixData::Vec { data, .. } => match self.schema[0] {
171                ModelMatrixSchema::RowName => DMatrix::<f64>::zeros(data.len(), 0),
172                ModelMatrixSchema::Level => as_level(data),
173                ModelMatrixSchema::Factor => as_factor("", data).1,
174                ModelMatrixSchema::Value => DMatrix::<f64>::from_column_slice(data.len(), 1, data),
175            },
176            ModelMatrixData::Matrix { data, .. } => {
177                let mut matrix = DMatrix::<f64>::zeros(data.nrows(), 0);
178
179                let schemas = &self.schema;
180
181                for i in 0..data.ncols() {
182                    let column = data.column(i);
183                    let schema = &schemas[i];
184
185                    match schema {
186                        ModelMatrixSchema::RowName => {}
187                        ModelMatrixSchema::Level => {
188                            let mut ncols = matrix.ncols();
189                            matrix = matrix.insert_column(ncols, 0.0);
190                            let x = column.as_slice();
191                            for (j, &v) in as_level(x).iter().enumerate() {
192                                ncols = matrix.ncols();
193                                matrix[(j, ncols - 1)] = v;
194                            }
195                        }
196                        ModelMatrixSchema::Factor => {
197                            let x = column.as_slice();
198                            let factor_matrix = as_factor("", x).1;
199                            for ii in 0..factor_matrix.ncols() {
200                                let mut ncols = matrix.ncols();
201                                matrix = matrix.insert_column(ncols, 0.0);
202                                for j in 0..factor_matrix.nrows() {
203                                    ncols = matrix.ncols();
204                                    matrix[(j, ncols - 1)] = factor_matrix[(j, ii)];
205                                }
206                            }
207                        }
208                        ModelMatrixSchema::Value => {
209                            let mut ncols = matrix.ncols();
210                            matrix = matrix.insert_column(ncols, 0.0);
211                            for (j, &v) in column.iter().enumerate() {
212                                ncols = matrix.ncols();
213                                matrix[(j, ncols - 1)] = v;
214                            }
215                        }
216                    }
217                }
218
219                matrix
220            }
221            ModelMatrixData::DataFrame(df) => {
222                let mut matrix = DMatrix::<f64>::zeros(df.height(), 0);
223
224                let data_names = df.get_column_names();
225                let data_types = df.dtypes();
226                let schemas = &self.schema;
227
228                for i in 0..df.width() {
229                    let column = &df[data_names[i]];
230                    let data_type = &data_types[i];
231                    let schema = &schemas[i];
232
233                    match schema {
234                        ModelMatrixSchema::RowName => {}
235                        ModelMatrixSchema::Level => match data_type {
236                            DataType::Boolean => {
237                                let mut c = Vec::new();
238                                column
239                                    .bool()
240                                    .unwrap()
241                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
242                                let mat = as_level(&c);
243
244                                let column_index_start = matrix.ncols();
245                                for column_number in 0..mat.ncols() {
246                                    let ncols = matrix.ncols();
247                                    matrix = matrix.insert_column(ncols, 0.0);
248                                    for j in 0..mat.nrows() {
249                                        matrix[(j, column_number + column_index_start)] =
250                                            mat[(j, column_number)];
251                                    }
252                                }
253                            }
254                            DataType::UInt8
255                            | DataType::UInt16
256                            | DataType::UInt32
257                            | DataType::UInt64
258                            | DataType::Int8
259                            | DataType::Int16
260                            | DataType::Int32
261                            | DataType::Int64
262                            | DataType::Float32
263                            | DataType::Float64 => {
264                                let mut c = Vec::new();
265                                column
266                                    .cast(&DataType::Float64)
267                                    .unwrap()
268                                    .f64()
269                                    .unwrap()
270                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
271                                let mat = as_level(&c);
272
273                                let column_index_start = matrix.ncols();
274                                for column_number in 0..mat.ncols() {
275                                    let ncols = matrix.ncols();
276                                    matrix = matrix.insert_column(ncols, 0.0);
277                                    for j in 0..mat.nrows() {
278                                        matrix[(j, column_number + column_index_start)] =
279                                            mat[(j, column_number)];
280                                    }
281                                }
282                            }
283                            DataType::String => {
284                                let mut c = Vec::new();
285                                column
286                                    .str()
287                                    .unwrap()
288                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
289                                let mat = as_level(&c);
290
291                                let column_index_start = matrix.ncols();
292                                for column_number in 0..mat.ncols() {
293                                    let ncols = matrix.ncols();
294                                    matrix = matrix.insert_column(ncols, 0.0);
295                                    for j in 0..mat.nrows() {
296                                        matrix[(j, column_number + column_index_start)] =
297                                            mat[(j, column_number)];
298                                    }
299                                }
300                            }
301                            DataType::Binary | DataType::BinaryOffset => {}
302                            DataType::Date
303                            | DataType::Datetime(_, _)
304                            | DataType::Duration(_)
305                            | DataType::Time => {}
306                            DataType::List(_) | DataType::Null | DataType::Unknown => {}
307                        },
308                        ModelMatrixSchema::Factor => match data_type {
309                            DataType::Boolean => {
310                                let mut c = Vec::new();
311                                column
312                                    .bool()
313                                    .unwrap()
314                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
315                                let (_, mat) = as_factor("", &c);
316
317                                let column_index_start = matrix.ncols();
318                                for column_number in 0..mat.ncols() {
319                                    let ncols = matrix.ncols();
320                                    matrix = matrix.insert_column(ncols, 0.0);
321                                    for j in 0..mat.nrows() {
322                                        matrix[(j, column_number + column_index_start)] =
323                                            mat[(j, column_number)];
324                                    }
325                                }
326                            }
327                            DataType::UInt8
328                            | DataType::UInt16
329                            | DataType::UInt32
330                            | DataType::UInt64
331                            | DataType::Int8
332                            | DataType::Int16
333                            | DataType::Int32
334                            | DataType::Int64
335                            | DataType::Float32
336                            | DataType::Float64 => {
337                                let mut c = Vec::new();
338                                column
339                                    .cast(&DataType::Float64)
340                                    .unwrap()
341                                    .f64()
342                                    .unwrap()
343                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
344                                let (_, mat) = as_factor("", &c);
345
346                                let column_index_start = matrix.ncols();
347                                for column_number in 0..mat.ncols() {
348                                    let ncols = matrix.ncols();
349                                    matrix = matrix.insert_column(ncols, 0.0);
350                                    for j in 0..mat.nrows() {
351                                        matrix[(j, column_number + column_index_start)] =
352                                            mat[(j, column_number)];
353                                    }
354                                }
355                            }
356                            DataType::String => {
357                                let mut c = Vec::new();
358                                column
359                                    .str()
360                                    .unwrap()
361                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
362                                let (_, mat) = as_factor("", &c);
363
364                                let column_index_start = matrix.ncols();
365                                for column_number in 0..mat.ncols() {
366                                    let ncols = matrix.ncols();
367                                    matrix = matrix.insert_column(ncols, 0.0);
368                                    for j in 0..mat.nrows() {
369                                        matrix[(j, column_number + column_index_start)] =
370                                            mat[(j, column_number)];
371                                    }
372                                }
373                            }
374                            DataType::Binary | DataType::BinaryOffset => {}
375                            DataType::Date
376                            | DataType::Datetime(_, _)
377                            | DataType::Duration(_)
378                            | DataType::Time => {}
379                            DataType::List(_) | DataType::Null | DataType::Unknown => {}
380                        },
381                        ModelMatrixSchema::Value => {
382                            let column_index = matrix.ncols();
383                            matrix = matrix.insert_column(column_index, 0.0);
384
385                            let mut c = Vec::new();
386                            match data_type {
387                                DataType::Boolean => {
388                                    column.bool().unwrap().for_each(|c_opt| {
389                                        c.push(if c_opt.unwrap() { 1.0 } else { 0.0 })
390                                    });
391                                }
392                                DataType::UInt8
393                                | DataType::UInt16
394                                | DataType::UInt32
395                                | DataType::UInt64
396                                | DataType::Int8
397                                | DataType::Int16
398                                | DataType::Int32
399                                | DataType::Int64
400                                | DataType::Float32
401                                | DataType::Float64 => {
402                                    column
403                                        .cast(&DataType::Float64)
404                                        .unwrap()
405                                        .f64()
406                                        .unwrap()
407                                        .for_each(|c_opt| c.push(c_opt.unwrap()));
408                                }
409                                DataType::String => {
410                                    column.str().unwrap().for_each(|c_opt| {
411                                        let c_unwrapped = c_opt.unwrap().to_string();
412                                        c.push(c_unwrapped.parse::<f64>().unwrap());
413                                    });
414                                }
415                                DataType::Binary | DataType::BinaryOffset => {}
416                                DataType::Date
417                                | DataType::Datetime(_, _)
418                                | DataType::Duration(_)
419                                | DataType::Time => {}
420                                DataType::List(_) | DataType::Null | DataType::Unknown => {}
421                            }
422
423                            for (j, c_j) in c.into_iter().enumerate() {
424                                matrix[(j, column_index)] = c_j;
425                            }
426                        }
427                    }
428                }
429
430                matrix
431            }
432        }
433    }
434
435    pub fn set_schema_index(&mut self, index: usize, schema: ModelMatrixSchema) {
436        self.schema[index] = schema;
437    }
438
439    pub fn set_schema_name(&mut self, name: &str, schema: ModelMatrixSchema) {
440        match &self.data {
441            ModelMatrixData::Vec { .. } => self.schema[0] = schema,
442            ModelMatrixData::Matrix { .. } => {
443                let index = name.replace("x", "").parse::<usize>().unwrap();
444                self.schema[index] = schema;
445            }
446            ModelMatrixData::DataFrame(df) => {
447                let name_index = df
448                    .get_column_names()
449                    .iter()
450                    .enumerate()
451                    .find(|(_, &n)| n == name)
452                    .unwrap()
453                    .0;
454                self.schema[name_index] = schema;
455            }
456        }
457    }
458
459    pub fn set_name(&mut self, old_name: &str, new_name: &str) {
460        match &mut self.data {
461            ModelMatrixData::Vec { name, .. } => {
462                *name = new_name.to_string();
463            }
464            ModelMatrixData::Matrix { names, .. } => {
465                for name in names {
466                    if name == old_name {
467                        *name = new_name.to_string();
468                    }
469                }
470            }
471            ModelMatrixData::DataFrame(df) => {
472                df.rename(old_name, new_name).unwrap();
473            }
474        }
475    }
476
477    pub fn set_name_index(&mut self, index: usize, name: &str) {
478        match &mut self.data {
479            ModelMatrixData::Vec { name, .. } => {
480                *name = name.to_string();
481            }
482            ModelMatrixData::Matrix { names, .. } => {
483                names[index] = name.to_string();
484            }
485            ModelMatrixData::DataFrame(df) => {
486                let old_name = df.get_column_names()[index].to_string();
487                df.rename(&old_name, name).unwrap();
488            }
489        }
490    }
491
492    pub fn column_names(&self) -> Vec<String> {
493        match &self.data {
494            ModelMatrixData::Vec { name, data } => match self.schema[0] {
495                ModelMatrixSchema::RowName => Vec::new(),
496                ModelMatrixSchema::Level | ModelMatrixSchema::Value => vec![name.clone()],
497                ModelMatrixSchema::Factor => as_factor(name, data).0,
498            },
499            ModelMatrixData::Matrix {
500                names: base_names,
501                data,
502            } => {
503                let mut names = Vec::new();
504                for i in 0..data.ncols() {
505                    match self.schema[i] {
506                        ModelMatrixSchema::RowName => {}
507                        ModelMatrixSchema::Level | ModelMatrixSchema::Value => {
508                            names.push(base_names[i].clone())
509                        }
510                        ModelMatrixSchema::Factor => {
511                            for name in as_factor(&base_names[i], data.column(i).as_slice()).0 {
512                                names.push(name);
513                            }
514                        }
515                    }
516                }
517                names
518            }
519            ModelMatrixData::DataFrame(df) => {
520                let mut names = Vec::new();
521
522                let data_names = df.get_column_names();
523                let data_types = df.dtypes();
524                let schemas = &self.schema;
525
526                for i in 0..df.width() {
527                    let column_name = data_names[i];
528                    let column = &df[column_name];
529                    let data_type = &data_types[i];
530                    let schema = &schemas[i];
531
532                    match schema {
533                        ModelMatrixSchema::RowName => {}
534                        ModelMatrixSchema::Value | ModelMatrixSchema::Level => {
535                            names.push(data_names[i].to_string())
536                        }
537                        ModelMatrixSchema::Factor => match data_type {
538                            DataType::Boolean => {
539                                let mut c = Vec::new();
540                                column
541                                    .bool()
542                                    .unwrap()
543                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
544                                let (mut new_names, _) = as_factor(column_name, &c);
545
546                                names.append(&mut new_names);
547                            }
548                            DataType::UInt8
549                            | DataType::UInt16
550                            | DataType::UInt32
551                            | DataType::UInt64
552                            | DataType::Int8
553                            | DataType::Int16
554                            | DataType::Int32
555                            | DataType::Int64
556                            | DataType::Float32
557                            | DataType::Float64 => {
558                                let mut c = Vec::new();
559                                column
560                                    .cast(&DataType::Float64)
561                                    .unwrap()
562                                    .f64()
563                                    .unwrap()
564                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
565                                let (mut new_names, _) = as_factor(column_name, &c);
566
567                                names.append(&mut new_names);
568                            }
569                            DataType::String => {
570                                let mut c = Vec::new();
571                                column
572                                    .str()
573                                    .unwrap()
574                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
575                                let (mut new_names, _) = as_factor(column_name, &c);
576
577                                names.append(&mut new_names);
578                            }
579                            DataType::Binary | DataType::BinaryOffset => {}
580                            DataType::Date
581                            | DataType::Datetime(_, _)
582                            | DataType::Duration(_)
583                            | DataType::Time => {}
584                            DataType::List(_) | DataType::Null | DataType::Unknown => {}
585                        },
586                    }
587                }
588
589                names
590            }
591        }
592    }
593
594    pub fn row_names(&self) -> Vec<String> {
595        match &self.data {
596            ModelMatrixData::Vec { data, .. } => {
597                if self.schema[0] == ModelMatrixSchema::RowName {
598                    data.iter().map(|d| d.to_string()).collect::<Vec<_>>()
599                } else {
600                    Vec::new()
601                }
602            }
603            ModelMatrixData::Matrix { data, .. } => {
604                let mut names = Vec::new();
605                for i in 0..data.ncols() {
606                    if self.schema[i] == ModelMatrixSchema::RowName {
607                        names = data.column(i).iter().map(|d| d.to_string()).collect();
608                        break;
609                    }
610                }
611                names
612            }
613            ModelMatrixData::DataFrame(df) => {
614                let mut names = Vec::new();
615
616                let data_names = df.get_column_names();
617                let data_types = df.dtypes();
618                let schemas = &self.schema;
619
620                for i in 0..df.width() {
621                    let column_name = data_names[i];
622                    let column = &df[column_name];
623                    let data_type = &data_types[i];
624                    let schema = schemas[i];
625
626                    if schema == ModelMatrixSchema::RowName {
627                        match data_type {
628                            DataType::Boolean => {
629                                let mut c = Vec::new();
630                                column
631                                    .bool()
632                                    .unwrap()
633                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
634                                names = c.into_iter().map(|b| b.to_string()).collect();
635                            }
636                            DataType::UInt8
637                            | DataType::UInt16
638                            | DataType::UInt32
639                            | DataType::UInt64
640                            | DataType::Int8
641                            | DataType::Int16
642                            | DataType::Int32
643                            | DataType::Int64
644                            | DataType::Float32
645                            | DataType::Float64 => {
646                                let mut c = Vec::new();
647                                column
648                                    .cast(&DataType::Float64)
649                                    .unwrap()
650                                    .f64()
651                                    .unwrap()
652                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
653                                names = c.into_iter().map(|f| f.to_string()).collect();
654                            }
655                            DataType::String => {
656                                let mut c = Vec::new();
657                                column
658                                    .str()
659                                    .unwrap()
660                                    .for_each(|c_opt| c.push(c_opt.unwrap()));
661                                names = c.into_iter().map(|s| s.to_string()).collect();
662                            }
663                            DataType::Binary | DataType::BinaryOffset => {}
664                            DataType::Date
665                            | DataType::Datetime(_, _)
666                            | DataType::Duration(_)
667                            | DataType::Time => {}
668                            DataType::List(_) | DataType::Null | DataType::Unknown => {}
669                        }
670                        break;
671                    }
672                }
673
674                names
675            }
676        }
677    }
678}
679
680impl Display for ModelMatrix {
681    fn fmt(&self, formatter: &mut Formatter) -> FmtResult {
682        writeln!(
683            formatter,
684            "({}, {})",
685            self.matrix().nrows(),
686            self.matrix().ncols()
687        )?;
688
689        let dp = DisplayTable::new(
690            self.column_names(),
691            self.row_names(),
692            self.matrix()
693                .row_iter()
694                .map(|r| r.iter().cloned().collect())
695                .collect(),
696            None,
697        );
698
699        writeln!(formatter, "{dp}")
700    }
701}
702
703impl From<&DataFrame> for ModelMatrix {
704    fn from(value: &DataFrame) -> Self {
705        Self::from(value.clone())
706    }
707}
708
709impl From<DataFrame> for ModelMatrix {
710    fn from(value: DataFrame) -> Self {
711        Self {
712            schema: value
713                .dtypes()
714                .into_iter()
715                .enumerate()
716                .filter_map(|(i, dtype)| {
717                    if i == 0 && value.get_column_names()[i].is_empty() {
718                        Some(ModelMatrixSchema::RowName)
719                    } else {
720                        match dtype {
721                            DataType::Boolean => Some(ModelMatrixSchema::Factor),
722                            DataType::UInt8
723                            | DataType::UInt16
724                            | DataType::UInt32
725                            | DataType::UInt64
726                            | DataType::Int8
727                            | DataType::Int16
728                            | DataType::Int32
729                            | DataType::Int64
730                            | DataType::Float32
731                            | DataType::Float64 => Some(ModelMatrixSchema::Value),
732                            DataType::String => Some(ModelMatrixSchema::Factor),
733                            DataType::Binary | DataType::BinaryOffset => None,
734                            DataType::Date
735                            | DataType::Datetime(_, _)
736                            | DataType::Duration(_)
737                            | DataType::Time => None,
738                            DataType::List(_) | DataType::Null | DataType::Unknown => None,
739                        }
740                    }
741                })
742                .collect(),
743            data: ModelMatrixData::DataFrame(value),
744        }
745    }
746}
747
748impl From<&DMatrix<f64>> for ModelMatrix {
749    fn from(value: &DMatrix<f64>) -> Self {
750        Self::from(value.clone())
751    }
752}
753
754impl From<DMatrix<f64>> for ModelMatrix {
755    fn from(value: DMatrix<f64>) -> Self {
756        Self {
757            schema: (0..value.ncols())
758                .map(|_| ModelMatrixSchema::Value)
759                .collect(),
760            data: ModelMatrixData::Matrix {
761                names: (0..value.ncols()).map(|i| format!("x{i}")).collect(),
762                data: value,
763            },
764        }
765    }
766}
767
768impl<T: Clone> From<Vec<T>> for ModelMatrix
769where
770    f64: From<T>,
771{
772    fn from(value: Vec<T>) -> Self {
773        Self::from(value.as_slice())
774    }
775}
776
777impl<T: Clone> From<&Vec<T>> for ModelMatrix
778where
779    f64: From<T>,
780{
781    fn from(value: &Vec<T>) -> Self {
782        Self::from(value.as_slice())
783    }
784}
785
786impl<T: Clone> From<&[T]> for ModelMatrix
787where
788    f64: From<T>,
789{
790    fn from(value: &[T]) -> Self {
791        Self {
792            data: ModelMatrixData::Vec {
793                name: "x".to_string(),
794                data: value.iter().map(|t| f64::from(t.clone())).collect(),
795            },
796            schema: vec![ModelMatrixSchema::Value],
797        }
798    }
799}