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