1use radiate_error::RadiateError;
2#[cfg(feature = "serde")]
3use serde::{Deserialize, Serialize};
4use std::fmt::Debug;
5use std::hash::Hash;
6use std::iter::Sum;
7use std::ops::{Add, Div, Index, Mul, Sub};
8use std::sync::Arc;
9
10pub trait Scored {
13 fn score(&self) -> Option<&Score>;
14}
15
16#[derive(Clone, PartialEq, Default)]
25#[repr(transparent)]
26pub struct Score {
27 values: Arc<[f32]>,
28}
29
30impl Score {
31 pub fn from_vec(values: Vec<f32>) -> Self {
32 Score {
33 values: Arc::from(values),
34 }
35 }
36
37 pub fn is_multi_objective(&self) -> bool {
38 self.values.len() > 1
39 }
40
41 pub fn is_single_objective(&self) -> bool {
42 self.values.len() == 1
43 }
44
45 pub fn objective(&self, idx: usize) -> Option<&f32> {
46 self.values.get(idx)
47 }
48
49 #[inline]
50 pub fn first(&self) -> Option<f32> {
51 self.values.first().cloned()
52 }
53
54 pub fn as_slice(&self) -> &[f32] {
55 &self.values
56 }
57
58 pub fn as_f32(&self) -> f32 {
59 self.values.first().cloned().unwrap_or(f32::NAN)
60 }
61
62 pub fn as_f64(&self) -> f64 {
63 self.values.first().cloned().unwrap_or(f32::NAN) as f64
64 }
65
66 pub fn as_i32(&self) -> i32 {
67 self.values[0] as i32
68 }
69
70 pub fn as_string(&self) -> String {
71 self.values[0].to_string()
72 }
73
74 pub fn as_usize(&self) -> usize {
75 self.values[0] as usize
76 }
77
78 pub fn iter(&self) -> impl Iterator<Item = &f32> + '_ {
79 self.values.iter()
80 }
81
82 pub fn len(&self) -> usize {
83 self.values.len()
84 }
85
86 pub fn is_empty(&self) -> bool {
87 self.values.is_empty()
88 }
89}
90
91impl AsRef<[f32]> for Score {
92 fn as_ref(&self) -> &[f32] {
93 &self.values
94 }
95}
96
97impl PartialOrd for Score {
98 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
99 self.values.partial_cmp(&other.values)
100 }
101}
102
103impl Debug for Score {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 write!(f, "{:?}", self.values)
106 }
107}
108
109impl Eq for Score {}
110
111impl Hash for Score {
112 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
113 let mut hash: usize = 0;
114
115 for value in self.values.iter() {
116 let value_hash = value.to_bits();
117 hash = hash.wrapping_add(value_hash as usize);
118 }
119
120 hash.hash(state);
121 }
122}
123
124impl Index<usize> for Score {
125 type Output = f32;
126 fn index(&self, index: usize) -> &Self::Output {
127 &self.values[index]
128 }
129}
130
131impl From<Score> for Vec<f32> {
132 fn from(score: Score) -> Vec<f32> {
133 score.values.to_vec()
134 }
135}
136
137impl From<f32> for Score {
138 fn from(value: f32) -> Self {
139 Score {
140 values: Arc::from(vec![value]),
141 }
142 }
143}
144
145impl TryFrom<i16> for Score {
146 type Error = RadiateError;
147
148 fn try_from(value: i16) -> Result<Self, Self::Error> {
149 Ok(Score {
150 values: Arc::from(vec![value as f32]),
151 })
152 }
153}
154
155impl From<f64> for Score {
156 fn from(value: f64) -> Self {
157 Score {
158 values: Arc::from(vec![value as f32]),
159 }
160 }
161}
162
163impl From<i32> for Score {
164 fn from(value: i32) -> Self {
165 Score {
166 values: Arc::from(vec![value as f32]),
167 }
168 }
169}
170
171impl From<i64> for Score {
172 fn from(value: i64) -> Self {
173 Score {
174 values: Arc::from(vec![value as f32]),
175 }
176 }
177}
178
179impl From<usize> for Score {
180 fn from(value: usize) -> Self {
181 Score {
182 values: Arc::from(vec![value as f32]),
183 }
184 }
185}
186
187impl From<String> for Score {
188 fn from(value: String) -> Self {
189 Score {
190 values: Arc::from(vec![
191 value.parse::<f32>().expect("Failed to parse string to f32"),
192 ]),
193 }
194 }
195}
196
197impl From<&str> for Score {
198 fn from(value: &str) -> Self {
199 Score {
200 values: Arc::from(vec![
201 value.parse::<f32>().expect("Failed to parse string to f32"),
202 ]),
203 }
204 }
205}
206
207impl From<Vec<f32>> for Score {
208 fn from(value: Vec<f32>) -> Self {
209 Score::from_vec(value)
210 }
211}
212
213impl From<Vec<f64>> for Score {
214 fn from(value: Vec<f64>) -> Self {
215 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
216 }
217}
218
219impl From<&[f32]> for Score {
220 fn from(value: &[f32]) -> Self {
221 Score::from_vec(value.to_vec())
222 }
223}
224
225impl From<&[f64]> for Score {
226 fn from(value: &[f64]) -> Self {
227 Score::from_vec(value.iter().map(|&v| v as f32).collect())
228 }
229}
230
231impl From<Vec<i32>> for Score {
232 fn from(value: Vec<i32>) -> Self {
233 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
234 }
235}
236
237impl From<Vec<i64>> for Score {
238 fn from(value: Vec<i64>) -> Self {
239 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
240 }
241}
242
243impl From<Vec<usize>> for Score {
244 fn from(value: Vec<usize>) -> Self {
245 Score::from_vec(value.into_iter().map(|v| v as f32).collect())
246 }
247}
248
249impl From<Vec<String>> for Score {
250 fn from(value: Vec<String>) -> Self {
251 Score::from_vec(
252 value
253 .into_iter()
254 .map(|v| v.parse::<f32>().unwrap())
255 .collect(),
256 )
257 }
258}
259
260impl From<Vec<&str>> for Score {
261 fn from(value: Vec<&str>) -> Self {
262 Score::from_vec(
263 value
264 .into_iter()
265 .map(|v| v.parse::<f32>().unwrap())
266 .collect(),
267 )
268 }
269}
270
271impl Add for Score {
272 type Output = Self;
273
274 fn add(self, other: Self) -> Self {
275 if self.values.is_empty() {
276 return other;
277 }
278
279 let mut values = Vec::with_capacity(self.values.len());
280
281 for i in 0..self.values.len() {
282 values.push(self.values[i] + other.values[i]);
283 }
284
285 Score {
286 values: Arc::from(values),
287 }
288 }
289}
290
291impl Add<f32> for Score {
292 type Output = Self;
293
294 fn add(self, other: f32) -> Self {
295 if self.values.is_empty() {
296 return Score::from(other);
297 }
298
299 let mut values = Vec::with_capacity(self.values.len());
300 for i in 0..self.values.len() {
301 values.push(self.values[i] + other);
302 }
303
304 Score {
305 values: values.into(),
306 }
307 }
308}
309
310impl Sub for Score {
311 type Output = Self;
312
313 fn sub(self, other: Self) -> Self {
314 if self.values.is_empty() {
315 return other;
316 }
317
318 let mut values = Vec::with_capacity(self.values.len());
319
320 for i in 0..self.values.len() {
321 values.push(self.values[i] - other.values[i]);
322 }
323
324 Score {
325 values: Arc::from(values),
326 }
327 }
328}
329
330impl Sub<f32> for Score {
331 type Output = Self;
332
333 fn sub(self, other: f32) -> Self {
334 if self.values.is_empty() {
335 return Score::from(-other);
336 }
337
338 let mut values = Vec::with_capacity(self.values.len());
339 for i in 0..self.values.len() {
340 values.push(self.values[i] - other);
341 }
342
343 Score {
344 values: Arc::from(values),
345 }
346 }
347}
348
349impl Mul for Score {
350 type Output = Self;
351
352 fn mul(self, other: Self) -> Self {
353 if self.values.is_empty() {
354 return other;
355 }
356
357 let mut values = Vec::with_capacity(self.values.len());
358 for i in 0..self.values.len() {
359 values.push(self.values[i] * other.values[i]);
360 }
361
362 Score {
363 values: Arc::from(values),
364 }
365 }
366}
367
368impl Mul<f32> for Score {
369 type Output = Self;
370
371 fn mul(self, other: f32) -> Self {
372 if self.values.is_empty() {
373 return Score::from(other);
374 }
375
376 let mut values = Vec::with_capacity(self.values.len());
377 for i in 0..self.values.len() {
378 values.push(self.values[i] * other);
379 }
380
381 Score {
382 values: Arc::from(values),
383 }
384 }
385}
386
387impl Mul<Score> for f32 {
388 type Output = Score;
389
390 fn mul(self, other: Score) -> Score {
391 if other.values.is_empty() {
392 return Score::from(self);
393 }
394
395 let mut values = Vec::with_capacity(other.values.len());
396 for i in 0..other.values.len() {
397 values.push(other.values[i] * self);
398 }
399
400 Score {
401 values: Arc::from(values),
402 }
403 }
404}
405
406impl Div for Score {
407 type Output = Self;
408
409 fn div(self, other: Self) -> Self {
410 if self.values.is_empty() {
411 return other;
412 }
413
414 let mut values = Vec::with_capacity(self.values.len());
415 for i in 0..self.values.len() {
416 values.push(self.values[i] / other.values[i]);
417 }
418
419 Score {
420 values: Arc::from(values),
421 }
422 }
423}
424
425impl Div<f32> for Score {
426 type Output = Self;
427
428 fn div(self, other: f32) -> Self {
429 if self.values.is_empty() {
430 return Score::from(other);
431 }
432
433 let mut values = Vec::with_capacity(self.values.len());
434 for i in 0..self.values.len() {
435 values.push(self.values[i] / other);
436 }
437
438 Score {
439 values: Arc::from(values),
440 }
441 }
442}
443
444impl Sum for Score {
445 fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
446 let mut values = vec![];
447
448 for score in iter {
449 for (i, value) in score.values.iter().enumerate() {
450 if values.len() <= i {
451 values.push(*value);
452 } else {
453 values[i] += value;
454 }
455 }
456 }
457
458 Score {
459 values: Arc::from(values),
460 }
461 }
462}
463
464impl<'a> Sum<&'a Score> for Score {
465 fn sum<I: Iterator<Item = &'a Score>>(iter: I) -> Self {
466 let mut values = vec![];
467
468 for score in iter {
469 for (i, value) in score.values.iter().enumerate() {
470 if values.len() <= i {
471 values.push(*value);
472 } else {
473 values[i] += value;
474 }
475 }
476 }
477
478 Score {
479 values: Arc::from(values),
480 }
481 }
482}
483
484#[cfg(feature = "serde")]
485impl Serialize for Score {
486 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
487 where
488 S: serde::Serializer,
489 {
490 self.values.as_ref().serialize(serializer)
491 }
492}
493
494#[cfg(feature = "serde")]
495impl<'de> Deserialize<'de> for Score {
496 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
497 where
498 D: serde::Deserializer<'de>,
499 {
500 let vec = Vec::<f32>::deserialize(deserializer)?;
501 for value in &vec {
502 if value.is_nan() {
503 return Err(serde::de::Error::custom("Score value cannot be NaN"));
504 }
505 }
506
507 Ok(Score {
508 values: Arc::from(vec),
509 })
510 }
511}
512
513#[cfg(test)]
514mod tests {
515 use super::*;
516
517 #[test]
518 fn test_score_from_vec() {
519 let score = Score::from(vec![1.0, 2.0, 3.0]);
520 assert_eq!(score.values.len(), 3);
521 }
522
523 #[test]
524 fn test_score_from_usize() {
525 let score = Score::from(3);
526 assert_eq!(score.values.len(), 1);
527 assert_eq!(score.as_f32(), 3.0);
528 assert_eq!(score.as_i32(), 3);
529 }
530
531 #[test]
532 fn test_score_from_f32() {
533 let score = Score::from(1.0);
534 assert_eq!(score.as_f32(), 1.0);
535 assert_eq!(score.as_i32(), 1)
536 }
537
538 #[test]
539 fn test_score_from_i32() {
540 let score = Score::from(-5);
541 assert_eq!(score.as_f32(), -5.0);
542 assert_eq!(score.as_i32(), -5);
543 }
544
545 #[test]
546 fn test_score_add() {
547 let score1 = Score::from(vec![1.0, 2.0, 3.0]);
548 let score2 = Score::from(vec![4.0, 5.0, 6.0]);
549 let score3 = score1 + score2;
550
551 assert_eq!(score3.values.len(), 3);
552 assert_eq!(score3.as_f32(), 5.0);
553 assert_eq!(score3[0], 5.0);
554 assert_eq!(score3[1], 7.0);
555 assert_eq!(score3[2], 9.0);
556 }
557
558 #[test]
559 fn test_score_sub() {
560 let score1 = Score::from(vec![5.0, 7.0, 9.0]);
561 let score2 = Score::from(vec![4.0, 5.0, 6.0]);
562 let score3 = score1 - score2;
563 assert_eq!(score3.values.len(), 3);
564 assert_eq!(score3.as_f32(), 1.0);
565 assert_eq!(score3[0], 1.0);
566 assert_eq!(score3[1], 2.0);
567 assert_eq!(score3[2], 3.0);
568 }
569
570 #[test]
571 fn test_score_mul() {
572 let score1 = Score::from(vec![1.0, 2.0, 3.0]);
573 let score2 = Score::from(vec![4.0, 5.0, 6.0]);
574 let score3 = score1 * score2;
575 assert_eq!(score3.values.len(), 3);
576 assert_eq!(score3.as_f32(), 4.0);
577 assert_eq!(score3[0], 4.0);
578 assert_eq!(score3[1], 10.0);
579 assert_eq!(score3[2], 18.0);
580 }
581
582 #[test]
583 fn test_score_div() {
584 let score1 = Score::from(vec![4.0, 8.0, 12.0]);
585 let score2 = Score::from(vec![2.0, 4.0, 6.0]);
586 let score3 = score1 / score2;
587 assert_eq!(score3.values.len(), 3);
588 assert_eq!(score3.as_f32(), 2.0);
589 assert_eq!(score3[0], 2.0);
590 assert_eq!(score3[1], 2.0);
591 assert_eq!(score3[2], 2.0);
592 }
593
594 #[test]
595 #[cfg(feature = "serde")]
596 fn test_score_can_serialize() {
597 let score = Score::from(vec![1.0, 2.0, 3.0]);
598 let serialized = serde_json::to_string(&score).expect("Failed to serialize Score");
599 let deserialized: Score =
600 serde_json::from_str(&serialized).expect("Failed to deserialize Score");
601 assert_eq!(score, deserialized);
602 }
603}