1use haagenti_core::{Error, Result};
37use xxhash_rust::xxh3::xxh3_64;
38
39use crate::tensor::{CompressionAlgorithm, DType, QuantizationMetadata};
40
41pub use haagenti_core::dct::{dct_1d, dct_1d_direct, dct_2d, idct_1d, idct_1d_direct, idct_2d};
43
44pub const HOLO_MAGIC: [u8; 4] = *b"HTNS";
48
49pub const HOLO_VERSION: u32 = 1;
51
52pub const HOLO_FLAG_HEADER_CHECKSUM: u16 = 0x0001;
54
55pub const HOLO_FLAG_FRAGMENT_CHECKSUMS: u16 = 0x0002;
57
58pub const HOLO_FLAG_QUANTIZATION: u16 = 0x0004;
60
61pub const HOLO_FLAG_QUALITY_CURVE: u16 = 0x0008;
63
64pub const HOLO_FLAG_ESSENTIAL_FIRST: u16 = 0x0010;
66
67pub const HOLO_FLAG_INTERLEAVED: u16 = 0x0020;
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
76#[repr(u8)]
77pub enum HolographicEncoding {
78 #[default]
84 Spectral = 0,
85
86 RandomProjection = 1,
91
92 LowRankDistributed = 2,
98}
99
100impl HolographicEncoding {
101 pub fn name(&self) -> &'static str {
103 match self {
104 HolographicEncoding::Spectral => "Spectral (DCT)",
105 HolographicEncoding::RandomProjection => "Random Projection (JL)",
106 HolographicEncoding::LowRankDistributed => "Low-Rank Distributed (SVD)",
107 }
108 }
109
110 pub fn default_quality_curve(&self) -> QualityCurve {
112 match self {
113 HolographicEncoding::Spectral => QualityCurve {
115 coefficients: [0.6, 0.3, 0.08, 0.02],
116 min_fragments: 1,
117 sufficient_fragments: 6,
118 },
119 HolographicEncoding::RandomProjection => QualityCurve {
121 coefficients: [0.1, 0.8, 0.08, 0.02],
122 min_fragments: 2,
123 sufficient_fragments: 6,
124 },
125 HolographicEncoding::LowRankDistributed => QualityCurve {
127 coefficients: [0.3, 0.5, 0.15, 0.05],
128 min_fragments: 1,
129 sufficient_fragments: 4,
130 },
131 }
132 }
133}
134
135impl TryFrom<u8> for HolographicEncoding {
136 type Error = Error;
137
138 fn try_from(value: u8) -> Result<Self> {
139 match value {
140 0 => Ok(HolographicEncoding::Spectral),
141 1 => Ok(HolographicEncoding::RandomProjection),
142 2 => Ok(HolographicEncoding::LowRankDistributed),
143 _ => Err(Error::corrupted(format!(
144 "unknown holographic encoding: {}",
145 value
146 ))),
147 }
148 }
149}
150
151#[derive(Debug, Clone, Copy, PartialEq)]
158pub struct QualityCurve {
159 pub coefficients: [f32; 4],
162
163 pub min_fragments: u16,
165
166 pub sufficient_fragments: u16,
168}
169
170impl Default for QualityCurve {
171 fn default() -> Self {
172 QualityCurve {
174 coefficients: [0.0, 1.0, 0.0, 0.0],
175 min_fragments: 1,
176 sufficient_fragments: 8,
177 }
178 }
179}
180
181impl QualityCurve {
182 pub fn new(coefficients: [f32; 4], min_fragments: u16, sufficient_fragments: u16) -> Self {
184 QualityCurve {
185 coefficients,
186 min_fragments,
187 sufficient_fragments,
188 }
189 }
190
191 pub fn linear() -> Self {
193 Self::default()
194 }
195
196 pub fn predict(&self, k: u16, n: u16) -> f32 {
200 if n == 0 {
201 return 0.0;
202 }
203 if k >= n {
204 return 1.0;
205 }
206 if k < self.min_fragments {
207 return 0.0;
208 }
209
210 let x = k as f32 / n as f32;
211 let mut result = 0.0f32;
212 let mut x_power = 1.0f32;
213
214 for &coeff in &self.coefficients {
215 result += coeff * x_power;
216 x_power *= x;
217 }
218
219 result.clamp(0.0, 1.0)
220 }
221
222 pub fn fragments_for_quality(&self, target: f32, total: u16) -> u16 {
224 for k in self.min_fragments..=total {
225 if self.predict(k, total) >= target {
226 return k;
227 }
228 }
229 total
230 }
231
232 pub fn to_bytes(&self) -> [u8; 16] {
234 let mut bytes = [0u8; 16];
235 for (i, &coeff) in self.coefficients.iter().enumerate() {
236 bytes[i * 4..(i + 1) * 4].copy_from_slice(&coeff.to_le_bytes());
237 }
238 bytes
239 }
240
241 pub fn from_bytes(bytes: &[u8; 16]) -> Self {
243 let mut coefficients = [0.0f32; 4];
244 for i in 0..4 {
245 coefficients[i] = f32::from_le_bytes([
246 bytes[i * 4],
247 bytes[i * 4 + 1],
248 bytes[i * 4 + 2],
249 bytes[i * 4 + 3],
250 ]);
251 }
252 QualityCurve {
254 coefficients,
255 min_fragments: 1,
256 sufficient_fragments: 8,
257 }
258 }
259}
260
261#[derive(Debug, Clone, PartialEq)]
268pub struct HoloFragment {
269 pub index: u16,
271
272 pub flags: u16,
274
275 pub checksum: u64,
277
278 pub data: Vec<u8>,
280}
281
282impl HoloFragment {
283 pub fn new(index: u16, data: Vec<u8>) -> Self {
285 let checksum = xxh3_64(&data);
286 HoloFragment {
287 index,
288 flags: 0,
289 checksum,
290 data,
291 }
292 }
293
294 pub fn with_checksum(index: u16, data: Vec<u8>, checksum: u64) -> Self {
296 HoloFragment {
297 index,
298 flags: 0,
299 checksum,
300 data,
301 }
302 }
303
304 pub fn verify_checksum(&self, uncompressed: &[u8]) -> bool {
306 xxh3_64(uncompressed) == self.checksum
307 }
308
309 pub fn data_size(&self) -> usize {
311 self.data.len()
312 }
313}
314
315#[derive(Debug, Clone, Copy, PartialEq, Eq)]
332pub struct FragmentIndexEntry {
333 pub index: u16,
335 pub flags: u16,
337 pub offset: u32,
339 pub compressed_size: u32,
341 pub uncompressed_size: u32,
343 pub checksum: u64,
345}
346
347impl FragmentIndexEntry {
348 pub const SIZE: usize = 24;
350
351 pub fn to_bytes(&self) -> [u8; Self::SIZE] {
353 let mut bytes = [0u8; Self::SIZE];
354 bytes[0..2].copy_from_slice(&self.index.to_le_bytes());
355 bytes[2..4].copy_from_slice(&self.flags.to_le_bytes());
356 bytes[4..8].copy_from_slice(&self.offset.to_le_bytes());
357 bytes[8..12].copy_from_slice(&self.compressed_size.to_le_bytes());
358 bytes[12..16].copy_from_slice(&self.uncompressed_size.to_le_bytes());
359 bytes[16..24].copy_from_slice(&self.checksum.to_le_bytes());
360 bytes
361 }
362
363 pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> Self {
365 FragmentIndexEntry {
366 index: u16::from_le_bytes([bytes[0], bytes[1]]),
367 flags: u16::from_le_bytes([bytes[2], bytes[3]]),
368 offset: u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
369 compressed_size: u32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]),
370 uncompressed_size: u32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]),
371 checksum: u64::from_le_bytes([
372 bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22],
373 bytes[23],
374 ]),
375 }
376 }
377}
378
379#[derive(Debug, Clone, PartialEq)]
405pub struct HoloTensorHeader {
406 pub encoding: HolographicEncoding,
408
409 pub compression: CompressionAlgorithm,
411
412 pub flags: u16,
414
415 pub total_fragments: u16,
417
418 pub min_fragments: u16,
420
421 pub original_size: u64,
423
424 pub seed: u64,
426
427 pub dtype: DType,
429
430 pub shape: Vec<u64>,
432
433 pub quality_curve: QualityCurve,
435
436 pub quantization: Option<QuantizationMetadata>,
438}
439
440impl HoloTensorHeader {
441 pub const BASE_SIZE: usize = 96;
443
444 pub fn new(
446 encoding: HolographicEncoding,
447 dtype: DType,
448 shape: Vec<u64>,
449 total_fragments: u16,
450 ) -> Self {
451 let quality_curve = encoding.default_quality_curve();
452 let original_size = shape.iter().product::<u64>() * dtype.bytes() as u64;
453
454 HoloTensorHeader {
455 encoding,
456 compression: CompressionAlgorithm::Zstd, flags: HOLO_FLAG_HEADER_CHECKSUM | HOLO_FLAG_FRAGMENT_CHECKSUMS,
458 total_fragments,
459 min_fragments: quality_curve.min_fragments,
460 original_size,
461 seed: 0,
462 dtype,
463 shape,
464 quality_curve,
465 quantization: None,
466 }
467 }
468
469 pub fn with_seed(mut self, seed: u64) -> Self {
471 self.seed = seed;
472 self
473 }
474
475 pub fn with_compression(mut self, compression: CompressionAlgorithm) -> Self {
477 self.compression = compression;
478 self
479 }
480
481 pub fn without_fragment_checksums(mut self) -> Self {
484 self.flags &= !HOLO_FLAG_FRAGMENT_CHECKSUMS;
485 self
486 }
487
488 pub fn with_quantization(mut self, quant: QuantizationMetadata) -> Self {
490 self.quantization = Some(quant);
491 self.flags |= HOLO_FLAG_QUANTIZATION;
492 self
493 }
494
495 pub fn with_quality_curve(mut self, curve: QualityCurve) -> Self {
497 self.quality_curve = curve;
498 self.min_fragments = curve.min_fragments;
499 self
500 }
501
502 pub fn num_elements(&self) -> u64 {
504 self.shape.iter().product()
505 }
506
507 pub fn fragment_data_size(&self) -> u64 {
509 self.original_size / self.total_fragments as u64 + 1024
512 }
513
514 pub fn to_bytes(&self) -> Vec<u8> {
516 let mut bytes = Vec::with_capacity(Self::BASE_SIZE);
517
518 bytes.extend_from_slice(&HOLO_MAGIC);
520
521 bytes.extend_from_slice(&HOLO_VERSION.to_le_bytes());
523
524 bytes.push(self.encoding as u8);
526
527 bytes.push(self.compression as u8);
529
530 bytes.extend_from_slice(&self.flags.to_le_bytes());
532
533 bytes.extend_from_slice(&self.total_fragments.to_le_bytes());
535
536 bytes.extend_from_slice(&self.min_fragments.to_le_bytes());
538
539 bytes.extend_from_slice(&self.original_size.to_le_bytes());
541
542 bytes.extend_from_slice(&self.seed.to_le_bytes());
544
545 bytes.push(self.dtype as u8);
547
548 bytes.push(self.shape.len() as u8);
550
551 for i in 0..4 {
553 let dim = self.shape.get(i).copied().unwrap_or(0);
554 bytes.extend_from_slice(&dim.to_le_bytes());
555 }
556
557 bytes.extend_from_slice(&self.quality_curve.to_bytes());
559
560 bytes.extend_from_slice(&[0u8; 6]);
562
563 let checksum = xxh3_64(&bytes);
565 bytes.extend_from_slice(&checksum.to_le_bytes());
566
567 bytes
568 }
569
570 pub fn from_bytes(bytes: &[u8]) -> Result<Self> {
572 if bytes.len() < Self::BASE_SIZE {
573 return Err(Error::corrupted("header too short"));
574 }
575
576 if bytes[0..4] != HOLO_MAGIC {
578 return Err(Error::corrupted("invalid magic bytes"));
579 }
580
581 let version = u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]);
583 if version != HOLO_VERSION {
584 return Err(Error::corrupted(format!(
585 "unsupported version: {}",
586 version
587 )));
588 }
589
590 let flags = u16::from_le_bytes([bytes[10], bytes[11]]);
592 if flags & HOLO_FLAG_HEADER_CHECKSUM != 0 {
593 let stored_checksum = u64::from_le_bytes([
594 bytes[88], bytes[89], bytes[90], bytes[91], bytes[92], bytes[93], bytes[94],
595 bytes[95],
596 ]);
597 let computed_checksum = xxh3_64(&bytes[0..88]);
598 if stored_checksum != computed_checksum {
599 return Err(Error::corrupted("header checksum mismatch"));
600 }
601 }
602
603 let encoding = HolographicEncoding::try_from(bytes[8])?;
604 let compression = CompressionAlgorithm::try_from(bytes[9])?;
605 let total_fragments = u16::from_le_bytes([bytes[12], bytes[13]]);
606 let min_fragments = u16::from_le_bytes([bytes[14], bytes[15]]);
607 let original_size = u64::from_le_bytes([
608 bytes[16], bytes[17], bytes[18], bytes[19], bytes[20], bytes[21], bytes[22], bytes[23],
609 ]);
610 let seed = u64::from_le_bytes([
611 bytes[24], bytes[25], bytes[26], bytes[27], bytes[28], bytes[29], bytes[30], bytes[31],
612 ]);
613 let dtype = DType::try_from(bytes[32])?;
614 let num_dims = bytes[33] as usize;
615
616 let mut shape = Vec::with_capacity(num_dims);
618 for i in 0..num_dims {
619 let offset = 34 + i * 8;
620 let dim = u64::from_le_bytes([
621 bytes[offset],
622 bytes[offset + 1],
623 bytes[offset + 2],
624 bytes[offset + 3],
625 bytes[offset + 4],
626 bytes[offset + 5],
627 bytes[offset + 6],
628 bytes[offset + 7],
629 ]);
630 shape.push(dim);
631 }
632
633 let mut curve_bytes = [0u8; 16];
635 curve_bytes.copy_from_slice(&bytes[66..82]);
636 let mut quality_curve = QualityCurve::from_bytes(&curve_bytes);
637 quality_curve.min_fragments = min_fragments;
638
639 Ok(HoloTensorHeader {
640 encoding,
641 compression,
642 flags,
643 total_fragments,
644 min_fragments,
645 original_size,
646 seed,
647 dtype,
648 shape,
649 quality_curve,
650 quantization: None, })
652 }
653}
654
655#[derive(Clone)]
659pub struct SeededRng {
660 state: u64,
661}
662
663impl SeededRng {
664 pub fn new(seed: u64) -> Self {
666 SeededRng {
667 state: seed.wrapping_add(1),
668 }
669 }
670
671 pub fn next_u64(&mut self) -> u64 {
673 let mut x = self.state;
674 x ^= x << 13;
675 x ^= x >> 7;
676 x ^= x << 17;
677 self.state = x;
678 x
679 }
680
681 pub fn next_f32(&mut self) -> f32 {
683 (self.next_u64() >> 40) as f32 / (1u64 << 24) as f32
684 }
685
686 pub fn next_normal(&mut self) -> f32 {
688 let u1 = self.next_f32().max(1e-10);
689 let u2 = self.next_f32();
690 (-2.0 * u1.ln()).sqrt() * (2.0 * std::f32::consts::PI * u2).cos()
691 }
692}
693
694pub struct SpectralEncoder {
707 num_fragments: u16,
708 essential_ratio: f32,
709}
710
711impl SpectralEncoder {
712 pub fn new(num_fragments: u16) -> Self {
714 SpectralEncoder {
715 num_fragments,
716 essential_ratio: 0.1, }
718 }
719
720 pub fn with_essential_ratio(mut self, ratio: f32) -> Self {
722 self.essential_ratio = ratio.clamp(0.01, 0.5);
723 self
724 }
725
726 pub fn encode_2d(
735 &self,
736 data: &[f32],
737 width: usize,
738 height: usize,
739 ) -> Result<Vec<HoloFragment>> {
740 let n = width * height;
741 if data.len() != n {
742 return Err(Error::corrupted("data size mismatch"));
743 }
744
745 let mut dct_coeffs = vec![0.0f32; n];
747 dct_2d(data, &mut dct_coeffs, width, height);
748
749 let num_fragments = self.num_fragments as usize;
750 let mut fragments = Vec::with_capacity(num_fragments);
751
752 const V3_MAGIC: u32 = 0x33305653;
754
755 for frag_idx in 0..self.num_fragments {
757 let mut frag_data = Vec::new();
758
759 let start = frag_idx as usize;
761 let count = n.saturating_sub(start).saturating_add(num_fragments - 1) / num_fragments;
763
764 frag_data.extend_from_slice(&V3_MAGIC.to_le_bytes());
766 frag_data.extend_from_slice(&(n as u32).to_le_bytes());
767 frag_data.extend_from_slice(&(self.num_fragments as u32).to_le_bytes());
768 frag_data.extend_from_slice(&(start as u32).to_le_bytes());
769 frag_data.extend_from_slice(&(count as u32).to_le_bytes());
770
771 for pos in (start..n).step_by(num_fragments) {
773 frag_data.extend_from_slice(&dct_coeffs[pos].to_le_bytes());
774 }
775
776 fragments.push(HoloFragment::new(frag_idx, frag_data));
777 }
778
779 Ok(fragments)
780 }
781
782 pub fn encode_1d(&self, data: &[f32]) -> Result<Vec<HoloFragment>> {
784 self.encode_2d(data, data.len(), 1)
785 }
786}
787
788const SPECTRAL_V2_MAGIC: u32 = 0x32305653;
792
793const SPECTRAL_V3_MAGIC: u32 = 0x33305653;
795
796pub struct SpectralDecoder {
807 width: usize,
808 height: usize,
809 accumulator: Vec<f32>,
810 coefficient_set: Vec<bool>,
811 fragments_loaded: u16,
812 total_fragments: u16,
813 is_v2: bool,
815 importance_order: Vec<u32>,
816 values_by_rank: Vec<f32>,
817 num_fragments_v2: usize,
818}
819
820impl SpectralDecoder {
821 pub fn new(width: usize, height: usize, total_fragments: u16) -> Self {
823 let n = width * height;
824 SpectralDecoder {
825 width,
826 height,
827 accumulator: vec![0.0f32; n],
828 coefficient_set: vec![false; n],
829 fragments_loaded: 0,
830 total_fragments,
831 is_v2: false,
833 importance_order: Vec::new(),
834 values_by_rank: vec![0.0f32; n],
835 num_fragments_v2: 0,
836 }
837 }
838
839 pub fn add_fragment(&mut self, fragment: &HoloFragment) -> Result<()> {
841 let data = &fragment.data;
842 if data.len() < 8 {
843 return Err(Error::corrupted("fragment too short"));
844 }
845
846 let magic = u32::from_le_bytes([data[0], data[1], data[2], data[3]]);
848
849 if magic == SPECTRAL_V3_MAGIC {
850 self.add_fragment_v3(fragment)
851 } else if magic == SPECTRAL_V2_MAGIC {
852 self.add_fragment_v2(fragment)
853 } else {
854 self.add_fragment_v1(fragment)
855 }
856 }
857
858 fn add_fragment_v1(&mut self, fragment: &HoloFragment) -> Result<()> {
860 let data = &fragment.data;
861 let _essential_count = u32::from_le_bytes([data[0], data[1], data[2], data[3]]) as usize;
862 let _detail_count = u32::from_le_bytes([data[4], data[5], data[6], data[7]]) as usize;
863
864 let mut offset = 8;
865 let coeff_size = 8; while offset + coeff_size <= data.len() {
869 let idx = u32::from_le_bytes([
870 data[offset],
871 data[offset + 1],
872 data[offset + 2],
873 data[offset + 3],
874 ]) as usize;
875 let value = f32::from_le_bytes([
876 data[offset + 4],
877 data[offset + 5],
878 data[offset + 6],
879 data[offset + 7],
880 ]);
881
882 if idx < self.accumulator.len() && !self.coefficient_set[idx] {
883 self.accumulator[idx] = value;
884 self.coefficient_set[idx] = true;
885 }
886
887 offset += coeff_size;
888 }
889
890 self.fragments_loaded += 1;
891 Ok(())
892 }
893
894 fn add_fragment_v2(&mut self, fragment: &HoloFragment) -> Result<()> {
896 let data = &fragment.data;
897 self.is_v2 = true;
898
899 if fragment.index == 0 {
900 if data.len() < 12 {
902 return Err(Error::corrupted("V2 fragment 0 too short"));
903 }
904
905 let num_coeffs = u32::from_le_bytes([data[4], data[5], data[6], data[7]]) as usize;
906 let num_fragments = u32::from_le_bytes([data[8], data[9], data[10], data[11]]) as usize;
907 self.num_fragments_v2 = num_fragments;
908
909 let order_start = 12;
911 let order_end = order_start + num_coeffs * 4;
912 if data.len() < order_end {
913 return Err(Error::corrupted("V2 importance order truncated"));
914 }
915
916 self.importance_order = Vec::with_capacity(num_coeffs);
917 for i in 0..num_coeffs {
918 let offset = order_start + i * 4;
919 let idx = u32::from_le_bytes([
920 data[offset],
921 data[offset + 1],
922 data[offset + 2],
923 data[offset + 3],
924 ]);
925 self.importance_order.push(idx);
926 }
927
928 let values_start = order_end;
930 let mut rank = 0usize;
931 let mut offset = values_start;
932 while offset + 4 <= data.len() && rank < num_coeffs {
933 let value = f32::from_le_bytes([
934 data[offset],
935 data[offset + 1],
936 data[offset + 2],
937 data[offset + 3],
938 ]);
939 self.values_by_rank[rank] = value;
940 rank += num_fragments;
941 offset += 4;
942 }
943 } else {
944 if data.len() < 12 {
946 return Err(Error::corrupted("V2 fragment too short"));
947 }
948
949 let slice_offset = u32::from_le_bytes([data[4], data[5], data[6], data[7]]) as usize;
950 let slice_count = u32::from_le_bytes([data[8], data[9], data[10], data[11]]) as usize;
951
952 let values_start = 12;
954 let num_fragments = self.num_fragments_v2.max(self.total_fragments as usize);
955 let mut rank = slice_offset;
956 let mut offset = values_start;
957 let mut count = 0;
958 while offset + 4 <= data.len() && count < slice_count {
959 let value = f32::from_le_bytes([
960 data[offset],
961 data[offset + 1],
962 data[offset + 2],
963 data[offset + 3],
964 ]);
965 if rank < self.values_by_rank.len() {
966 self.values_by_rank[rank] = value;
967 }
968 rank += num_fragments;
969 offset += 4;
970 count += 1;
971 }
972 }
973
974 self.fragments_loaded += 1;
975 Ok(())
976 }
977
978 fn add_fragment_v3(&mut self, fragment: &HoloFragment) -> Result<()> {
980 let data = &fragment.data;
981
982 if data.len() < 20 {
984 return Err(Error::corrupted("V3 fragment too short"));
985 }
986
987 let num_coeffs = u32::from_le_bytes([data[4], data[5], data[6], data[7]]) as usize;
988 let num_fragments = u32::from_le_bytes([data[8], data[9], data[10], data[11]]) as usize;
989 let slice_offset = u32::from_le_bytes([data[12], data[13], data[14], data[15]]) as usize;
990 let _slice_count = u32::from_le_bytes([data[16], data[17], data[18], data[19]]) as usize;
991
992 self.num_fragments_v2 = num_fragments;
993
994 let values_start = 20;
996 let mut pos = slice_offset;
997 let mut offset = values_start;
998 while offset + 4 <= data.len() && pos < num_coeffs {
999 let value = f32::from_le_bytes([
1000 data[offset],
1001 data[offset + 1],
1002 data[offset + 2],
1003 data[offset + 3],
1004 ]);
1005 if pos < self.accumulator.len() {
1006 self.accumulator[pos] = value;
1007 self.coefficient_set[pos] = true;
1008 }
1009 pos += num_fragments;
1010 offset += 4;
1011 }
1012
1013 self.fragments_loaded += 1;
1014 Ok(())
1015 }
1016
1017 pub fn quality(&self) -> f32 {
1019 if self.is_v2 {
1020 self.fragments_loaded as f32 / self.total_fragments as f32
1022 } else {
1023 let set_count = self.coefficient_set.iter().filter(|&&x| x).count();
1024 set_count as f32 / self.accumulator.len() as f32
1025 }
1026 }
1027
1028 pub fn reconstruct(&self) -> Vec<f32> {
1030 let n = self.width * self.height;
1031 let mut output = vec![0.0f32; n];
1032
1033 if self.is_v2 {
1034 let mut coeffs = vec![0.0f32; n];
1036 for (rank, &value) in self.values_by_rank.iter().enumerate() {
1037 if rank < self.importance_order.len() {
1038 let coeff_idx = self.importance_order[rank] as usize;
1039 if coeff_idx < n {
1040 coeffs[coeff_idx] = value;
1041 }
1042 }
1043 }
1044 idct_2d(&coeffs, &mut output, self.width, self.height);
1045 } else {
1046 idct_2d(&self.accumulator, &mut output, self.width, self.height);
1048 }
1049
1050 output
1051 }
1052
1053 pub fn can_reconstruct(&self) -> bool {
1055 if self.is_v2 {
1056 self.fragments_loaded >= 1 && !self.importance_order.is_empty()
1058 } else {
1059 self.fragments_loaded >= 1
1060 }
1061 }
1062
1063 pub fn fragments_loaded(&self) -> u16 {
1065 self.fragments_loaded
1066 }
1067}
1068
1069pub struct RphEncoder {
1073 num_fragments: u16,
1074 projection_dim: usize,
1075 seed: u64,
1076}
1077
1078impl RphEncoder {
1079 pub fn new(num_fragments: u16, seed: u64) -> Self {
1081 RphEncoder {
1082 num_fragments,
1083 projection_dim: 0, seed,
1085 }
1086 }
1087
1088 pub fn with_projection_dim(mut self, dim: usize) -> Self {
1090 self.projection_dim = dim;
1091 self
1092 }
1093
1094 pub fn encode(&self, data: &[f32]) -> Result<Vec<HoloFragment>> {
1098 let n = data.len();
1099 let proj_dim = if self.projection_dim > 0 {
1100 self.projection_dim
1101 } else {
1102 (n / self.num_fragments as usize).max(64)
1105 };
1106
1107 let mut fragments = Vec::with_capacity(self.num_fragments as usize);
1108
1109 for frag_idx in 0..self.num_fragments {
1110 let frag_seed = self
1112 .seed
1113 .wrapping_add((frag_idx as u64).wrapping_mul(0x9E3779B97F4A7C15));
1114 let mut rng = SeededRng::new(frag_seed);
1115
1116 let mut projection = vec![0.0f32; proj_dim];
1118 let scale = 1.0 / (proj_dim as f32).sqrt();
1119
1120 for p in projection.iter_mut() {
1121 let mut sum = 0.0f32;
1122 for &x in data.iter() {
1123 sum += x * rng.next_normal();
1124 }
1125 *p = sum * scale;
1126 }
1127
1128 let mut frag_data = Vec::with_capacity(4 + 8 + proj_dim * 4);
1130 frag_data.extend_from_slice(&(proj_dim as u32).to_le_bytes());
1131 frag_data.extend_from_slice(&frag_seed.to_le_bytes());
1132 for &p in &projection {
1133 frag_data.extend_from_slice(&p.to_le_bytes());
1134 }
1135
1136 fragments.push(HoloFragment::new(frag_idx, frag_data));
1137 }
1138
1139 Ok(fragments)
1140 }
1141}
1142
1143pub struct RphDecoder {
1147 output_dim: usize,
1148 accumulator: Vec<f32>,
1149 weight_sum: Vec<f32>,
1150 fragments_loaded: u16,
1151 total_fragments: u16,
1152}
1153
1154impl RphDecoder {
1155 pub fn new(output_dim: usize, total_fragments: u16) -> Self {
1157 RphDecoder {
1158 output_dim,
1159 accumulator: vec![0.0f32; output_dim],
1160 weight_sum: vec![0.0f32; output_dim],
1161 fragments_loaded: 0,
1162 total_fragments,
1163 }
1164 }
1165
1166 pub fn add_fragment(&mut self, fragment: &HoloFragment) -> Result<()> {
1168 let data = &fragment.data;
1169 if data.len() < 12 {
1170 return Err(Error::corrupted("fragment too short"));
1171 }
1172
1173 let proj_dim = u32::from_le_bytes([data[0], data[1], data[2], data[3]]) as usize;
1174 let frag_seed = u64::from_le_bytes([
1175 data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11],
1176 ]);
1177
1178 if data.len() < 12 + proj_dim * 4 {
1179 return Err(Error::corrupted("fragment data incomplete"));
1180 }
1181
1182 let mut projection = Vec::with_capacity(proj_dim);
1184 let mut offset = 12;
1185 for _ in 0..proj_dim {
1186 let val = f32::from_le_bytes([
1187 data[offset],
1188 data[offset + 1],
1189 data[offset + 2],
1190 data[offset + 3],
1191 ]);
1192 projection.push(val);
1193 offset += 4;
1194 }
1195
1196 let mut rng = SeededRng::new(frag_seed);
1198 let scale = 1.0 / (proj_dim as f32).sqrt();
1199
1200 for &p in &projection {
1201 for i in 0..self.output_dim {
1202 let proj_val = rng.next_normal() * scale;
1203 self.accumulator[i] += p * proj_val;
1204 self.weight_sum[i] += proj_val * proj_val;
1205 }
1206 }
1207
1208 self.fragments_loaded += 1;
1209 Ok(())
1210 }
1211
1212 pub fn reconstruct(&self) -> Vec<f32> {
1214 self.accumulator
1215 .iter()
1216 .zip(self.weight_sum.iter())
1217 .map(|(&acc, &w)| if w > 1e-10 { acc / w } else { 0.0 })
1218 .collect()
1219 }
1220
1221 pub fn quality(&self) -> f32 {
1223 self.fragments_loaded as f32 / self.total_fragments as f32
1224 }
1225
1226 pub fn fragments_loaded(&self) -> u16 {
1228 self.fragments_loaded
1229 }
1230}
1231
1232fn svd_power_iteration(
1237 matrix: &[f32],
1238 rows: usize,
1239 cols: usize,
1240 rank: usize,
1241 iterations: usize,
1242) -> (Vec<f32>, Vec<f32>, Vec<f32>) {
1243 let mut u = vec![0.0f32; rows * rank];
1245 let mut s = vec![0.0f32; rank];
1246 let mut v = vec![0.0f32; cols * rank];
1247
1248 let mut residual = matrix.to_vec();
1249 let mut rng = SeededRng::new(42);
1250
1251 for r in 0..rank {
1252 let mut vec_v: Vec<f32> = (0..cols).map(|_| rng.next_normal()).collect();
1254
1255 for _ in 0..iterations {
1257 let mut vec_u = vec![0.0f32; rows];
1259 for i in 0..rows {
1260 let mut sum = 0.0f32;
1261 for j in 0..cols {
1262 sum += residual[i * cols + j] * vec_v[j];
1263 }
1264 vec_u[i] = sum;
1265 }
1266
1267 let norm_u: f32 = vec_u.iter().map(|x| x * x).sum::<f32>().sqrt();
1269 if norm_u > 1e-10 {
1270 for x in &mut vec_u {
1271 *x /= norm_u;
1272 }
1273 }
1274
1275 vec_v = vec![0.0f32; cols];
1277 for i in 0..rows {
1278 for j in 0..cols {
1279 vec_v[j] += residual[i * cols + j] * vec_u[i];
1280 }
1281 }
1282
1283 let norm_v: f32 = vec_v.iter().map(|x| x * x).sum::<f32>().sqrt();
1285 if norm_v > 1e-10 {
1286 for x in &mut vec_v {
1287 *x /= norm_v;
1288 }
1289 }
1290 }
1291
1292 let mut av = vec![0.0f32; rows];
1294 for i in 0..rows {
1295 let mut sum = 0.0f32;
1296 for j in 0..cols {
1297 sum += residual[i * cols + j] * vec_v[j];
1298 }
1299 av[i] = sum;
1300 }
1301 let sigma: f32 = av.iter().map(|x| x * x).sum::<f32>().sqrt();
1302
1303 let u_norm: f32 = av.iter().map(|x| x * x).sum::<f32>().sqrt();
1305 for i in 0..rows {
1306 u[i * rank + r] = if u_norm > 1e-10 { av[i] / u_norm } else { 0.0 };
1307 }
1308 s[r] = sigma;
1309 for j in 0..cols {
1310 v[j * rank + r] = vec_v[j];
1311 }
1312
1313 for i in 0..rows {
1315 for j in 0..cols {
1316 residual[i * cols + j] -= sigma * u[i * rank + r] * v[j * rank + r];
1317 }
1318 }
1319 }
1320
1321 (u, s, v)
1322}
1323
1324pub struct LrdfEncoder {
1326 num_fragments: u16,
1327 max_rank: usize,
1328}
1329
1330impl LrdfEncoder {
1331 pub fn new(num_fragments: u16) -> Self {
1333 LrdfEncoder {
1334 num_fragments,
1335 max_rank: 256, }
1337 }
1338
1339 pub fn with_max_rank(mut self, rank: usize) -> Self {
1341 self.max_rank = rank;
1342 self
1343 }
1344
1345 pub fn encode_2d(&self, data: &[f32], rows: usize, cols: usize) -> Result<Vec<HoloFragment>> {
1347 if data.len() != rows * cols {
1348 return Err(Error::corrupted("data size mismatch"));
1349 }
1350
1351 let rank = self.max_rank.min(rows.min(cols));
1353 let (u, s, v) = svd_power_iteration(data, rows, cols, rank, 20);
1354
1355 let components_per_frag = rank.div_ceil(self.num_fragments as usize);
1358
1359 let mut fragments = Vec::with_capacity(self.num_fragments as usize);
1360
1361 for frag_idx in 0..self.num_fragments {
1362 let start = frag_idx as usize * components_per_frag;
1363 let end = ((frag_idx as usize + 1) * components_per_frag).min(rank);
1364
1365 if start >= rank {
1366 let mut frag_data = Vec::new();
1368 frag_data.extend_from_slice(&(rows as u32).to_le_bytes());
1369 frag_data.extend_from_slice(&(cols as u32).to_le_bytes());
1370 frag_data.extend_from_slice(&0u32.to_le_bytes());
1371 fragments.push(HoloFragment::new(frag_idx, frag_data));
1372 continue;
1373 }
1374
1375 let num_components = end - start;
1376 let mut frag_data = Vec::new();
1377
1378 frag_data.extend_from_slice(&(rows as u32).to_le_bytes());
1380 frag_data.extend_from_slice(&(cols as u32).to_le_bytes());
1381 frag_data.extend_from_slice(&(num_components as u32).to_le_bytes());
1382
1383 for r in start..end {
1385 frag_data.extend_from_slice(&s[r].to_le_bytes());
1386
1387 for i in 0..rows {
1388 frag_data.extend_from_slice(&u[i * rank + r].to_le_bytes());
1389 }
1390
1391 for j in 0..cols {
1392 frag_data.extend_from_slice(&v[j * rank + r].to_le_bytes());
1393 }
1394 }
1395
1396 fragments.push(HoloFragment::new(frag_idx, frag_data));
1397 }
1398
1399 Ok(fragments)
1400 }
1401}
1402
1403pub struct LrdfDecoder {
1407 rows: usize,
1408 cols: usize,
1409 accumulator: Vec<f32>,
1410 fragments_loaded: u16,
1411 total_fragments: u16,
1412}
1413
1414impl LrdfDecoder {
1415 pub fn new(rows: usize, cols: usize, total_fragments: u16) -> Self {
1417 LrdfDecoder {
1418 rows,
1419 cols,
1420 accumulator: vec![0.0f32; rows * cols],
1421 fragments_loaded: 0,
1422 total_fragments,
1423 }
1424 }
1425
1426 pub fn add_fragment(&mut self, fragment: &HoloFragment) -> Result<()> {
1432 let data = &fragment.data;
1433 if data.len() < 12 {
1434 return Err(Error::corrupted("fragment too short"));
1435 }
1436
1437 let rows = u32::from_le_bytes([data[0], data[1], data[2], data[3]]) as usize;
1438 let cols = u32::from_le_bytes([data[4], data[5], data[6], data[7]]) as usize;
1439 let num_components = u32::from_le_bytes([data[8], data[9], data[10], data[11]]);
1440
1441 if rows != self.rows || cols != self.cols {
1442 return Err(Error::corrupted("dimension mismatch"));
1443 }
1444
1445 if num_components == 0xFFFFFFFF {
1447 let expected_size = 12 + rows * cols * 4;
1449 if data.len() < expected_size {
1450 return Err(Error::corrupted(format!(
1451 "raw fragment too short: {} < {}",
1452 data.len(),
1453 expected_size
1454 )));
1455 }
1456
1457 let mut offset = 12;
1459 for i in 0..rows * cols {
1460 let val = f32::from_le_bytes([
1461 data[offset],
1462 data[offset + 1],
1463 data[offset + 2],
1464 data[offset + 3],
1465 ]);
1466 self.accumulator[i] += val;
1467 offset += 4;
1468 }
1469
1470 self.fragments_loaded += 1;
1471 return Ok(());
1472 }
1473
1474 let num_components = num_components as usize;
1476 let mut offset = 12;
1477 let component_size = 4 + rows * 4 + cols * 4;
1478
1479 for _ in 0..num_components {
1480 if offset + component_size > data.len() {
1481 break;
1482 }
1483
1484 let sigma = f32::from_le_bytes([
1486 data[offset],
1487 data[offset + 1],
1488 data[offset + 2],
1489 data[offset + 3],
1490 ]);
1491 offset += 4;
1492
1493 let mut u = Vec::with_capacity(rows);
1495 for _ in 0..rows {
1496 let val = f32::from_le_bytes([
1497 data[offset],
1498 data[offset + 1],
1499 data[offset + 2],
1500 data[offset + 3],
1501 ]);
1502 u.push(val);
1503 offset += 4;
1504 }
1505
1506 let mut v = Vec::with_capacity(cols);
1508 for _ in 0..cols {
1509 let val = f32::from_le_bytes([
1510 data[offset],
1511 data[offset + 1],
1512 data[offset + 2],
1513 data[offset + 3],
1514 ]);
1515 v.push(val);
1516 offset += 4;
1517 }
1518
1519 for i in 0..rows {
1521 for j in 0..cols {
1522 self.accumulator[i * cols + j] += sigma * u[i] * v[j];
1523 }
1524 }
1525 }
1526
1527 self.fragments_loaded += 1;
1528 Ok(())
1529 }
1530
1531 pub fn reconstruct(&self) -> Vec<f32> {
1533 self.accumulator.clone()
1534 }
1535
1536 pub fn quality(&self) -> f32 {
1538 self.fragments_loaded as f32 / self.total_fragments as f32
1539 }
1540
1541 pub fn fragments_loaded(&self) -> u16 {
1543 self.fragments_loaded
1544 }
1545}
1546
1547pub struct HoloTensorEncoder {
1553 encoding: HolographicEncoding,
1554 num_fragments: u16,
1555 seed: u64,
1556 compression: CompressionAlgorithm,
1557 essential_ratio: f32,
1558 max_rank: usize,
1559}
1560
1561impl HoloTensorEncoder {
1562 pub fn new(encoding: HolographicEncoding) -> Self {
1564 HoloTensorEncoder {
1565 encoding,
1566 num_fragments: 8,
1567 seed: 0,
1568 compression: CompressionAlgorithm::Lz4,
1569 essential_ratio: 0.1,
1570 max_rank: 256, }
1572 }
1573
1574 pub fn with_fragments(mut self, n: u16) -> Self {
1576 self.num_fragments = n.max(1);
1577 self
1578 }
1579
1580 pub fn with_seed(mut self, seed: u64) -> Self {
1582 self.seed = seed;
1583 self
1584 }
1585
1586 pub fn with_compression(mut self, algo: CompressionAlgorithm) -> Self {
1588 self.compression = algo;
1589 self
1590 }
1591
1592 pub fn with_essential_ratio(mut self, ratio: f32) -> Self {
1594 self.essential_ratio = ratio.clamp(0.01, 0.5);
1595 self
1596 }
1597
1598 pub fn with_max_rank(mut self, rank: usize) -> Self {
1600 self.max_rank = rank;
1601 self
1602 }
1603
1604 fn encode_2d_internal(
1607 &self,
1608 data: &[f32],
1609 rows: usize,
1610 cols: usize,
1611 ) -> Result<Vec<HoloFragment>> {
1612 match self.encoding {
1613 HolographicEncoding::Spectral => SpectralEncoder::new(self.num_fragments)
1614 .with_essential_ratio(self.essential_ratio)
1615 .encode_2d(data, cols, rows),
1616 HolographicEncoding::RandomProjection => {
1617 RphEncoder::new(self.num_fragments, self.seed).encode(data)
1618 }
1619 HolographicEncoding::LowRankDistributed => LrdfEncoder::new(self.num_fragments)
1620 .with_max_rank(self.max_rank)
1621 .encode_2d(data, rows, cols),
1622 }
1623 }
1624
1625 fn flatten_shape(shape: &[usize]) -> (usize, usize) {
1627 match shape.len() {
1628 0 => (1, 1),
1629 1 => (1, shape[0]),
1630 2 => (shape[0], shape[1]),
1631 _ => {
1632 let first = shape[0];
1634 let rest: usize = shape[1..].iter().product();
1635 (first, rest)
1636 }
1637 }
1638 }
1639
1640 pub fn encode_nd(
1657 &self,
1658 data: &[f32],
1659 shape: &[usize],
1660 ) -> Result<(HoloTensorHeader, Vec<HoloFragment>)> {
1661 let expected_len: usize = shape.iter().product();
1663 if data.len() != expected_len {
1664 return Err(Error::corrupted(format!(
1665 "data length {} does not match shape {:?} (expected {})",
1666 data.len(),
1667 shape,
1668 expected_len
1669 )));
1670 }
1671
1672 let (rows, cols) = Self::flatten_shape(shape);
1674 let fragments = self.encode_2d_internal(data, rows, cols)?;
1675
1676 let header = HoloTensorHeader::new(
1678 self.encoding,
1679 DType::F32,
1680 shape.iter().map(|&d| d as u64).collect(),
1681 self.num_fragments,
1682 )
1683 .with_seed(self.seed)
1684 .with_compression(self.compression);
1685
1686 Ok((header, fragments))
1687 }
1688
1689 pub fn encode_2d(
1691 &self,
1692 data: &[f32],
1693 rows: usize,
1694 cols: usize,
1695 ) -> Result<(HoloTensorHeader, Vec<HoloFragment>)> {
1696 self.encode_nd(data, &[rows, cols])
1697 }
1698
1699 pub fn encode_1d(&self, data: &[f32]) -> Result<(HoloTensorHeader, Vec<HoloFragment>)> {
1703 self.encode_nd(data, &[data.len()])
1704 }
1705}
1706
1707enum DecoderState {
1711 Spectral(SpectralDecoder),
1712 Rph(RphDecoder),
1713 Lrdf(LrdfDecoder),
1714}
1715
1716pub struct HoloTensorDecoder {
1720 header: HoloTensorHeader,
1721 state: DecoderState,
1722}
1723
1724impl HoloTensorDecoder {
1725 pub fn new(header: HoloTensorHeader) -> Self {
1733 let (rows, cols) = match header.shape.len() {
1734 0 => (1, 1),
1735 1 => (1, header.shape[0] as usize),
1736 2 => (header.shape[0] as usize, header.shape[1] as usize),
1737 _ => {
1738 let first = header.shape[0] as usize;
1740 let rest: usize = header.shape[1..].iter().map(|&d| d as usize).product();
1741 (first, rest)
1742 }
1743 };
1744
1745 let state = match header.encoding {
1746 HolographicEncoding::Spectral => {
1747 DecoderState::Spectral(SpectralDecoder::new(cols, rows, header.total_fragments))
1748 }
1749 HolographicEncoding::RandomProjection => {
1750 DecoderState::Rph(RphDecoder::new(rows * cols, header.total_fragments))
1751 }
1752 HolographicEncoding::LowRankDistributed => {
1753 DecoderState::Lrdf(LrdfDecoder::new(rows, cols, header.total_fragments))
1754 }
1755 };
1756
1757 HoloTensorDecoder { header, state }
1758 }
1759
1760 pub fn add_fragment(&mut self, fragment: HoloFragment) -> Result<f32> {
1762 match &mut self.state {
1763 DecoderState::Spectral(dec) => dec.add_fragment(&fragment)?,
1764 DecoderState::Rph(dec) => dec.add_fragment(&fragment)?,
1765 DecoderState::Lrdf(dec) => dec.add_fragment(&fragment)?,
1766 }
1767 Ok(self.quality())
1768 }
1769
1770 pub fn quality(&self) -> f32 {
1772 match &self.state {
1773 DecoderState::Spectral(dec) => dec.quality(),
1774 DecoderState::Rph(dec) => dec.quality(),
1775 DecoderState::Lrdf(dec) => dec.quality(),
1776 }
1777 }
1778
1779 pub fn fragments_loaded(&self) -> u16 {
1781 match &self.state {
1782 DecoderState::Spectral(dec) => dec.fragments_loaded(),
1783 DecoderState::Rph(dec) => dec.fragments_loaded(),
1784 DecoderState::Lrdf(dec) => dec.fragments_loaded(),
1785 }
1786 }
1787
1788 pub fn can_reconstruct(&self) -> bool {
1790 self.fragments_loaded() >= 1
1791 }
1792
1793 pub fn reconstruct(&self) -> Result<Vec<f32>> {
1795 if !self.can_reconstruct() {
1796 return Err(Error::corrupted("no fragments loaded"));
1797 }
1798
1799 let data = match &self.state {
1800 DecoderState::Spectral(dec) => dec.reconstruct(),
1801 DecoderState::Rph(dec) => dec.reconstruct(),
1802 DecoderState::Lrdf(dec) => dec.reconstruct(),
1803 };
1804
1805 Ok(data)
1806 }
1807
1808 pub fn header(&self) -> &HoloTensorHeader {
1810 &self.header
1811 }
1812}
1813
1814use std::io::{Read, Seek, SeekFrom, Write};
1817
1818pub struct HoloTensorWriter<W: Write + Seek> {
1849 writer: W,
1850}
1851
1852impl<W: Write + Seek> HoloTensorWriter<W> {
1853 pub fn new(writer: W) -> Self {
1855 HoloTensorWriter { writer }
1856 }
1857
1858 pub fn write(&mut self, header: &HoloTensorHeader, fragments: &[HoloFragment]) -> Result<u64> {
1860 let header_bytes = header.to_bytes();
1862 self.writer
1863 .write_all(&header_bytes)
1864 .map_err(|e| Error::corrupted(format!("failed to write header: {}", e)))?;
1865
1866 let index_size = fragments.len() * FragmentIndexEntry::SIZE;
1868 let mut data_offset: u32 = 0;
1869 let mut index_entries = Vec::with_capacity(fragments.len());
1870
1871 for frag in fragments {
1873 let entry = FragmentIndexEntry {
1874 index: frag.index,
1875 flags: frag.flags,
1876 offset: data_offset,
1877 compressed_size: frag.data.len() as u32,
1878 uncompressed_size: frag.data.len() as u32, checksum: frag.checksum,
1880 };
1881 index_entries.push(entry);
1882 data_offset += frag.data.len() as u32;
1883 }
1884
1885 for entry in &index_entries {
1887 self.writer
1888 .write_all(&entry.to_bytes())
1889 .map_err(|e| Error::corrupted(format!("failed to write fragment index: {}", e)))?;
1890 }
1891
1892 for frag in fragments {
1894 self.writer
1895 .write_all(&frag.data)
1896 .map_err(|e| Error::corrupted(format!("failed to write fragment data: {}", e)))?;
1897 }
1898
1899 let total_size = header_bytes.len() as u64 + index_size as u64 + data_offset as u64;
1900 Ok(total_size)
1901 }
1902
1903 pub fn into_inner(self) -> W {
1905 self.writer
1906 }
1907}
1908
1909pub struct HoloTensorReader<R: Read + Seek> {
1936 reader: R,
1937 header: HoloTensorHeader,
1938 index: Vec<FragmentIndexEntry>,
1939 data_offset: u64,
1940 inline_entry: Option<FragmentIndexEntry>,
1944}
1945
1946impl<R: Read + Seek> HoloTensorReader<R> {
1947 pub fn new(mut reader: R) -> Result<Self> {
1949 let mut header_bytes = [0u8; HoloTensorHeader::BASE_SIZE];
1951 reader
1952 .read_exact(&mut header_bytes)
1953 .map_err(|e| Error::corrupted(format!("failed to read header: {}", e)))?;
1954
1955 let header = HoloTensorHeader::from_bytes(&header_bytes)?;
1956
1957 let index_size = header.total_fragments as usize * FragmentIndexEntry::SIZE;
1959 let mut index_bytes = vec![0u8; index_size];
1960 reader
1961 .read_exact(&mut index_bytes)
1962 .map_err(|e| Error::corrupted(format!("failed to read fragment index: {}", e)))?;
1963
1964 let mut index = Vec::with_capacity(header.total_fragments as usize);
1966 for i in 0..header.total_fragments as usize {
1967 let offset = i * FragmentIndexEntry::SIZE;
1968 let mut entry_bytes = [0u8; FragmentIndexEntry::SIZE];
1969 entry_bytes.copy_from_slice(&index_bytes[offset..offset + FragmentIndexEntry::SIZE]);
1970 index.push(FragmentIndexEntry::from_bytes(&entry_bytes));
1971 }
1972
1973 let data_offset = HoloTensorHeader::BASE_SIZE as u64 + index_size as u64;
1975
1976 let inline_entry = if header.total_fragments == 0 {
1980 let mut entry_bytes = [0u8; FragmentIndexEntry::SIZE];
1982 if reader.read_exact(&mut entry_bytes).is_ok() {
1983 let entry = FragmentIndexEntry::from_bytes(&entry_bytes);
1984 if entry.index == 0
1986 && entry.compressed_size > 0
1987 && entry.compressed_size < 1_000_000_000
1988 {
1989 Some(entry)
1990 } else {
1991 reader
1993 .seek(SeekFrom::Start(data_offset))
1994 .map_err(|e| Error::corrupted(format!("failed to seek: {}", e)))?;
1995 None
1996 }
1997 } else {
1998 None
1999 }
2000 } else {
2001 None
2002 };
2003
2004 Ok(HoloTensorReader {
2005 reader,
2006 header,
2007 index,
2008 data_offset,
2009 inline_entry,
2010 })
2011 }
2012
2013 pub fn header(&self) -> &HoloTensorHeader {
2015 &self.header
2016 }
2017
2018 pub fn fragment_index(&self) -> &[FragmentIndexEntry] {
2020 &self.index
2021 }
2022
2023 pub fn total_fragments(&self) -> u16 {
2026 if self.inline_entry.is_some() {
2027 1
2028 } else {
2029 self.header.total_fragments
2030 }
2031 }
2032
2033 pub fn is_inline_format(&self) -> bool {
2035 self.inline_entry.is_some()
2036 }
2037
2038 pub fn read_fragment(&mut self, fragment_index: u16) -> Result<HoloFragment> {
2040 if let Some(ref entry) = self.inline_entry {
2042 if fragment_index != 0 {
2043 return Err(Error::corrupted(format!(
2044 "inline format only has fragment 0, requested {}",
2045 fragment_index
2046 )));
2047 }
2048 return self.read_inline_fragment(*entry);
2049 }
2050
2051 let entry = self
2053 .index
2054 .iter()
2055 .find(|e| e.index == fragment_index)
2056 .ok_or_else(|| Error::corrupted(format!("fragment {} not found", fragment_index)))?;
2057
2058 let seek_pos = self.data_offset + entry.offset as u64;
2060 self.reader
2061 .seek(SeekFrom::Start(seek_pos))
2062 .map_err(|e| Error::corrupted(format!("failed to seek to fragment: {}", e)))?;
2063
2064 let mut data = vec![0u8; entry.compressed_size as usize];
2066 self.reader
2067 .read_exact(&mut data)
2068 .map_err(|e| Error::corrupted(format!("failed to read fragment data: {}", e)))?;
2069
2070 if self.header.flags & HOLO_FLAG_FRAGMENT_CHECKSUMS != 0 {
2072 let computed = xxh3_64(&data);
2073 if computed != entry.checksum {
2074 return Err(Error::corrupted(format!(
2075 "fragment {} checksum mismatch: expected {:016x}, got {:016x}",
2076 fragment_index, entry.checksum, computed
2077 )));
2078 }
2079 }
2080
2081 let decompressed_data = if entry.flags & 0x0001 != 0 {
2084 zstd::decode_all(&data[..]).map_err(|e| {
2085 Error::corrupted(format!(
2086 "failed to decompress fragment {}: {}",
2087 fragment_index, e
2088 ))
2089 })?
2090 } else {
2091 data
2092 };
2093
2094 Ok(HoloFragment {
2095 index: entry.index,
2096 flags: entry.flags,
2097 checksum: entry.checksum,
2098 data: decompressed_data,
2099 })
2100 }
2101
2102 fn read_inline_fragment(&mut self, entry: FragmentIndexEntry) -> Result<HoloFragment> {
2104 let data_start = self.data_offset + FragmentIndexEntry::SIZE as u64 + entry.offset as u64;
2107 self.reader
2108 .seek(SeekFrom::Start(data_start))
2109 .map_err(|e| Error::corrupted(format!("failed to seek to inline fragment: {}", e)))?;
2110
2111 let mut data = vec![0u8; entry.compressed_size as usize];
2113 self.reader
2114 .read_exact(&mut data)
2115 .map_err(|e| Error::corrupted(format!("failed to read inline fragment data: {}", e)))?;
2116
2117 if self.header.flags & HOLO_FLAG_FRAGMENT_CHECKSUMS != 0 {
2119 let computed = xxh3_64(&data);
2120 if computed != entry.checksum {
2121 return Err(Error::corrupted(format!(
2122 "inline fragment checksum mismatch: expected {:016x}, got {:016x}",
2123 entry.checksum, computed
2124 )));
2125 }
2126 }
2127
2128 let decompressed_data = if entry.flags & 0x0001 != 0 {
2130 zstd::decode_all(&data[..]).map_err(|e| {
2131 Error::corrupted(format!("failed to decompress inline fragment: {}", e))
2132 })?
2133 } else {
2134 data
2135 };
2136
2137 Ok(HoloFragment {
2138 index: entry.index,
2139 flags: entry.flags,
2140 checksum: entry.checksum,
2141 data: decompressed_data,
2142 })
2143 }
2144
2145 pub fn read_all(&mut self) -> Result<(HoloTensorHeader, Vec<HoloFragment>)> {
2149 let total = self.total_fragments();
2150 let mut fragments = Vec::with_capacity(total as usize);
2151
2152 for i in 0..total {
2153 fragments.push(self.read_fragment(i)?);
2154 }
2155
2156 Ok((self.header.clone(), fragments))
2157 }
2158
2159 pub fn read_to_quality(&mut self, target_quality: f32) -> Result<(Vec<HoloFragment>, f32)> {
2165 let total = self.total_fragments();
2166 let curve = self.header.quality_curve; let mut fragments = Vec::new();
2169 let mut quality = 0.0f32;
2170
2171 for i in 0..total {
2172 fragments.push(self.read_fragment(i)?);
2173 quality = curve.predict(i + 1, total.max(1)); if quality >= target_quality {
2176 break;
2177 }
2178 }
2179
2180 if self.is_inline_format() {
2182 quality = 1.0;
2183 }
2184
2185 Ok((fragments, quality))
2186 }
2187
2188 pub fn into_inner(self) -> R {
2190 self.reader
2191 }
2192}
2193
2194pub fn write_holotensor<P: AsRef<std::path::Path>>(
2210 path: P,
2211 header: &HoloTensorHeader,
2212 fragments: &[HoloFragment],
2213) -> Result<u64> {
2214 let file = std::fs::File::create(path.as_ref())
2215 .map_err(|e| Error::corrupted(format!("failed to create file: {}", e)))?;
2216 let writer = std::io::BufWriter::new(file);
2217 let mut holo_writer = HoloTensorWriter::new(writer);
2218 holo_writer.write(header, fragments)
2219}
2220
2221pub fn read_holotensor<P: AsRef<std::path::Path>>(
2237 path: P,
2238) -> Result<(HoloTensorHeader, Vec<HoloFragment>)> {
2239 let file = std::fs::File::open(path.as_ref())
2240 .map_err(|e| Error::corrupted(format!("failed to open file: {}", e)))?;
2241 let reader = std::io::BufReader::new(file);
2242 let mut holo_reader = HoloTensorReader::new(reader)?;
2243 holo_reader.read_all()
2244}
2245
2246pub fn open_holotensor<P: AsRef<std::path::Path>>(
2268 path: P,
2269) -> Result<HoloTensorReader<std::io::BufReader<std::fs::File>>> {
2270 let file = std::fs::File::open(path.as_ref())
2271 .map_err(|e| Error::corrupted(format!("failed to open file: {}", e)))?;
2272 let reader = std::io::BufReader::new(file);
2273 HoloTensorReader::new(reader)
2274}
2275
2276pub fn encode_to_file<P: AsRef<std::path::Path>>(
2287 path: P,
2288 data: &[f32],
2289 width: usize,
2290 height: usize,
2291 encoding: HolographicEncoding,
2292 num_fragments: u16,
2293) -> Result<u64> {
2294 let encoder = HoloTensorEncoder::new(encoding).with_fragments(num_fragments);
2295 let (header, fragments) = encoder.encode_2d(data, width, height)?;
2296 write_holotensor(path, &header, &fragments)
2297}
2298
2299pub fn decode_from_file<P: AsRef<std::path::Path>>(path: P) -> Result<Vec<f32>> {
2311 let (header, fragments) = read_holotensor(path)?;
2312 let mut decoder = HoloTensorDecoder::new(header);
2313 for frag in fragments {
2314 decoder.add_fragment(frag)?;
2315 }
2316 decoder.reconstruct()
2317}
2318
2319pub fn decode_from_file_progressive<P: AsRef<std::path::Path>>(
2333 path: P,
2334 target_quality: f32,
2335) -> Result<(Vec<f32>, f32)> {
2336 let mut reader = open_holotensor(path)?;
2337 let (fragments, quality) = reader.read_to_quality(target_quality)?;
2338
2339 let mut decoder = HoloTensorDecoder::new(reader.header().clone());
2340 for frag in fragments {
2341 decoder.add_fragment(frag)?;
2342 }
2343
2344 let data = decoder.reconstruct()?;
2345 Ok((data, quality))
2346}
2347
2348#[cfg(test)]
2351mod tests {
2352 use super::*;
2353
2354 #[test]
2357 fn test_encoding_default_is_spectral() {
2358 let encoding = HolographicEncoding::default();
2359 assert_eq!(encoding, HolographicEncoding::Spectral);
2360 }
2361
2362 #[test]
2363 fn test_encoding_try_from_valid() {
2364 assert_eq!(
2365 HolographicEncoding::try_from(0).unwrap(),
2366 HolographicEncoding::Spectral
2367 );
2368 assert_eq!(
2369 HolographicEncoding::try_from(1).unwrap(),
2370 HolographicEncoding::RandomProjection
2371 );
2372 assert_eq!(
2373 HolographicEncoding::try_from(2).unwrap(),
2374 HolographicEncoding::LowRankDistributed
2375 );
2376 }
2377
2378 #[test]
2379 fn test_encoding_try_from_invalid() {
2380 assert!(HolographicEncoding::try_from(3).is_err());
2381 assert!(HolographicEncoding::try_from(255).is_err());
2382 }
2383
2384 #[test]
2385 fn test_encoding_names() {
2386 assert!(HolographicEncoding::Spectral.name().contains("DCT"));
2387 assert!(HolographicEncoding::RandomProjection.name().contains("JL"));
2388 assert!(HolographicEncoding::LowRankDistributed
2389 .name()
2390 .contains("SVD"));
2391 }
2392
2393 #[test]
2394 fn test_encoding_default_curves_valid() {
2395 for encoding in [
2396 HolographicEncoding::Spectral,
2397 HolographicEncoding::RandomProjection,
2398 HolographicEncoding::LowRankDistributed,
2399 ] {
2400 let curve = encoding.default_quality_curve();
2401 assert!(curve.min_fragments >= 1);
2402 assert!(curve.sufficient_fragments >= curve.min_fragments);
2403 let full_quality = curve.predict(8, 8);
2405 assert!(
2406 full_quality > 0.95,
2407 "encoding {:?} full quality: {}",
2408 encoding,
2409 full_quality
2410 );
2411 }
2412 }
2413
2414 #[test]
2417 fn test_quality_curve_linear() {
2418 let curve = QualityCurve::linear();
2419
2420 assert_eq!(curve.predict(0, 8), 0.0);
2421 assert!((curve.predict(4, 8) - 0.5).abs() < 0.01);
2422 assert_eq!(curve.predict(8, 8), 1.0);
2423 }
2424
2425 #[test]
2426 fn test_quality_curve_predict_edge_cases() {
2427 let curve = QualityCurve::default();
2428
2429 assert_eq!(curve.predict(0, 0), 0.0);
2431
2432 assert_eq!(curve.predict(10, 8), 1.0);
2434 }
2435
2436 #[test]
2437 fn test_quality_curve_predict_respects_min_fragments() {
2438 let curve = QualityCurve {
2439 coefficients: [0.0, 1.0, 0.0, 0.0],
2440 min_fragments: 3,
2441 sufficient_fragments: 8,
2442 };
2443
2444 assert_eq!(curve.predict(1, 8), 0.0);
2445 assert_eq!(curve.predict(2, 8), 0.0);
2446 assert!(curve.predict(3, 8) > 0.0);
2447 }
2448
2449 #[test]
2450 fn test_quality_curve_fragments_for_quality() {
2451 let curve = QualityCurve::linear();
2452
2453 assert_eq!(curve.fragments_for_quality(0.5, 8), 4);
2454 assert_eq!(curve.fragments_for_quality(0.9, 8), 8); assert_eq!(curve.fragments_for_quality(1.1, 8), 8); }
2457
2458 #[test]
2459 fn test_quality_curve_serialization_roundtrip() {
2460 let curve = QualityCurve {
2461 coefficients: [0.6, 0.3, 0.08, 0.02],
2462 min_fragments: 2,
2463 sufficient_fragments: 6,
2464 };
2465
2466 let bytes = curve.to_bytes();
2467 let restored = QualityCurve::from_bytes(&bytes);
2468
2469 for i in 0..4 {
2470 assert!((curve.coefficients[i] - restored.coefficients[i]).abs() < 1e-6);
2471 }
2472 }
2473
2474 #[test]
2475 fn test_quality_curve_spectral_shape() {
2476 let curve = HolographicEncoding::Spectral.default_quality_curve();
2478
2479 let q1 = curve.predict(1, 8);
2480 let q4 = curve.predict(4, 8);
2481 let q8 = curve.predict(8, 8);
2482
2483 assert!(q1 > 0.5, "spectral q1={} should be > 0.5", q1);
2485 assert!(q4 > q1);
2487 assert!(q8 > q4);
2488 }
2489
2490 #[test]
2493 fn test_fragment_new_computes_checksum() {
2494 let data = vec![1, 2, 3, 4, 5];
2495 let fragment = HoloFragment::new(0, data.clone());
2496
2497 assert_eq!(fragment.index, 0);
2498 assert_eq!(fragment.checksum, xxh3_64(&data));
2499 assert_eq!(fragment.data, data);
2500 }
2501
2502 #[test]
2503 fn test_fragment_verify_checksum_valid() {
2504 let data = vec![1, 2, 3, 4, 5];
2505 let fragment = HoloFragment::new(0, data.clone());
2506
2507 assert!(fragment.verify_checksum(&data));
2508 }
2509
2510 #[test]
2511 fn test_fragment_verify_checksum_invalid() {
2512 let data = vec![1, 2, 3, 4, 5];
2513 let fragment = HoloFragment::new(0, data);
2514
2515 let corrupted = vec![1, 2, 3, 4, 6];
2516 assert!(!fragment.verify_checksum(&corrupted));
2517 }
2518
2519 #[test]
2520 fn test_fragment_with_checksum() {
2521 let data = vec![1, 2, 3, 4, 5];
2522 let original_checksum = xxh3_64(&[10, 20, 30]); let fragment = HoloFragment::with_checksum(5, data.clone(), original_checksum);
2525
2526 assert_eq!(fragment.index, 5);
2527 assert_eq!(fragment.checksum, original_checksum);
2528 assert!(!fragment.verify_checksum(&data)); }
2530
2531 #[test]
2534 fn test_fragment_index_entry_serialization_roundtrip() {
2535 let entry = FragmentIndexEntry {
2536 index: 42,
2537 flags: 0x0003,
2538 offset: 1024,
2539 compressed_size: 512,
2540 uncompressed_size: 1000,
2541 checksum: 0xDEADBEEFCAFEBABE,
2542 };
2543
2544 let bytes = entry.to_bytes();
2545 assert_eq!(bytes.len(), FragmentIndexEntry::SIZE);
2546
2547 let restored = FragmentIndexEntry::from_bytes(&bytes);
2548 assert_eq!(entry, restored);
2549 }
2550
2551 #[test]
2552 fn test_fragment_index_entry_size() {
2553 assert_eq!(FragmentIndexEntry::SIZE, 24);
2554 }
2555
2556 #[test]
2559 fn test_header_new_default_flags() {
2560 let header = HoloTensorHeader::new(
2561 HolographicEncoding::Spectral,
2562 DType::F32,
2563 vec![4096, 4096],
2564 8,
2565 );
2566
2567 assert!(header.flags & HOLO_FLAG_HEADER_CHECKSUM != 0);
2568 assert!(header.flags & HOLO_FLAG_FRAGMENT_CHECKSUMS != 0);
2569 }
2570
2571 #[test]
2572 fn test_header_calculates_original_size() {
2573 let header =
2574 HoloTensorHeader::new(HolographicEncoding::Spectral, DType::F32, vec![100, 200], 8);
2575
2576 assert_eq!(header.original_size, 80000);
2578 }
2579
2580 #[test]
2581 fn test_header_builder_pattern() {
2582 let header = HoloTensorHeader::new(
2583 HolographicEncoding::RandomProjection,
2584 DType::F16,
2585 vec![1024],
2586 4,
2587 )
2588 .with_seed(12345)
2589 .with_compression(CompressionAlgorithm::Zstd);
2590
2591 assert_eq!(header.seed, 12345);
2592 assert_eq!(header.compression, CompressionAlgorithm::Zstd);
2593 }
2594
2595 #[test]
2596 fn test_header_serialization_roundtrip() {
2597 let header = HoloTensorHeader::new(
2598 HolographicEncoding::LowRankDistributed,
2599 DType::BF16,
2600 vec![2048, 2048],
2601 16,
2602 )
2603 .with_seed(0xDEADBEEF)
2604 .with_compression(CompressionAlgorithm::Zstd);
2605
2606 let bytes = header.to_bytes();
2607 assert_eq!(bytes.len(), HoloTensorHeader::BASE_SIZE);
2608
2609 let restored = HoloTensorHeader::from_bytes(&bytes).unwrap();
2610
2611 assert_eq!(restored.encoding, header.encoding);
2612 assert_eq!(restored.compression, header.compression);
2613 assert_eq!(restored.total_fragments, header.total_fragments);
2614 assert_eq!(restored.min_fragments, header.min_fragments);
2615 assert_eq!(restored.original_size, header.original_size);
2616 assert_eq!(restored.seed, header.seed);
2617 assert_eq!(restored.dtype, header.dtype);
2618 assert_eq!(restored.shape, header.shape);
2619 }
2620
2621 #[test]
2622 fn test_header_invalid_magic() {
2623 let mut bytes =
2624 HoloTensorHeader::new(HolographicEncoding::Spectral, DType::F32, vec![100], 4)
2625 .to_bytes();
2626
2627 bytes[0] = 0xFF;
2629
2630 assert!(HoloTensorHeader::from_bytes(&bytes).is_err());
2631 }
2632
2633 #[test]
2634 fn test_header_checksum_validation() {
2635 let header = HoloTensorHeader::new(HolographicEncoding::Spectral, DType::F32, vec![100], 4);
2636
2637 let mut bytes = header.to_bytes();
2638
2639 bytes[20] ^= 0xFF;
2641
2642 assert!(HoloTensorHeader::from_bytes(&bytes).is_err());
2644 }
2645
2646 #[test]
2647 fn test_header_num_elements() {
2648 let header = HoloTensorHeader::new(
2649 HolographicEncoding::Spectral,
2650 DType::F32,
2651 vec![10, 20, 30],
2652 8,
2653 );
2654
2655 assert_eq!(header.num_elements(), 6000);
2656 }
2657
2658 #[test]
2659 fn test_header_various_dtypes() {
2660 for dtype in [DType::F32, DType::F16, DType::BF16, DType::I8, DType::I4] {
2661 let header = HoloTensorHeader::new(HolographicEncoding::Spectral, dtype, vec![100], 4);
2662
2663 let bytes = header.to_bytes();
2664 let restored = HoloTensorHeader::from_bytes(&bytes).unwrap();
2665
2666 assert_eq!(restored.dtype, dtype);
2667 }
2668 }
2669
2670 #[test]
2671 fn test_header_various_shapes() {
2672 let h1 = HoloTensorHeader::new(HolographicEncoding::Spectral, DType::F32, vec![100], 4);
2674 let r1 = HoloTensorHeader::from_bytes(&h1.to_bytes()).unwrap();
2675 assert_eq!(r1.shape, vec![100]);
2676
2677 let h2 = HoloTensorHeader::new(HolographicEncoding::Spectral, DType::F32, vec![10, 20], 4);
2679 let r2 = HoloTensorHeader::from_bytes(&h2.to_bytes()).unwrap();
2680 assert_eq!(r2.shape, vec![10, 20]);
2681
2682 let h3 = HoloTensorHeader::new(HolographicEncoding::Spectral, DType::F32, vec![2, 3, 4], 4);
2684 let r3 = HoloTensorHeader::from_bytes(&h3.to_bytes()).unwrap();
2685 assert_eq!(r3.shape, vec![2, 3, 4]);
2686
2687 let h4 = HoloTensorHeader::new(
2689 HolographicEncoding::Spectral,
2690 DType::F32,
2691 vec![1, 2, 3, 4],
2692 4,
2693 );
2694 let r4 = HoloTensorHeader::from_bytes(&h4.to_bytes()).unwrap();
2695 assert_eq!(r4.shape, vec![1, 2, 3, 4]);
2696 }
2697
2698 #[test]
2701 fn test_dct_1d_roundtrip() {
2702 let input = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
2703 let mut dct_out = vec![0.0f32; 8];
2704 let mut idct_out = vec![0.0f32; 8];
2705
2706 dct_1d(&input, &mut dct_out);
2707 idct_1d(&dct_out, &mut idct_out);
2708
2709 for (a, b) in input.iter().zip(idct_out.iter()) {
2710 assert!((a - b).abs() < 1e-5, "DCT roundtrip failed: {} vs {}", a, b);
2711 }
2712 }
2713
2714 #[test]
2715 fn test_dct_2d_roundtrip() {
2716 let input: Vec<f32> = (0..16).map(|i| i as f32).collect();
2717 let mut dct_out = vec![0.0f32; 16];
2718 let mut idct_out = vec![0.0f32; 16];
2719
2720 dct_2d(&input, &mut dct_out, 4, 4);
2721 idct_2d(&dct_out, &mut idct_out, 4, 4);
2722
2723 for (a, b) in input.iter().zip(idct_out.iter()) {
2724 assert!(
2725 (a - b).abs() < 1e-4,
2726 "2D DCT roundtrip failed: {} vs {}",
2727 a,
2728 b
2729 );
2730 }
2731 }
2732
2733 #[test]
2734 fn test_dct_energy_compaction() {
2735 let input: Vec<f32> = (0..64).map(|i| (i as f32 * 0.1).sin()).collect();
2737 let mut dct_out = vec![0.0f32; 64];
2738
2739 dct_2d(&input, &mut dct_out, 8, 8);
2740
2741 let total_energy: f32 = dct_out.iter().map(|x| x * x).sum();
2743 let low_freq_energy: f32 = dct_out[..16].iter().map(|x| x * x).sum();
2744
2745 assert!(
2746 low_freq_energy / total_energy > 0.5,
2747 "Energy compaction failed"
2748 );
2749 }
2750
2751 #[test]
2754 fn test_seeded_rng_deterministic() {
2755 let mut rng1 = SeededRng::new(12345);
2756 let mut rng2 = SeededRng::new(12345);
2757
2758 for _ in 0..100 {
2759 assert_eq!(rng1.next_u64(), rng2.next_u64());
2760 }
2761 }
2762
2763 #[test]
2764 fn test_seeded_rng_different_seeds() {
2765 let mut rng1 = SeededRng::new(1);
2766 let mut rng2 = SeededRng::new(2);
2767
2768 let v1: Vec<u64> = (0..10).map(|_| rng1.next_u64()).collect();
2769 let v2: Vec<u64> = (0..10).map(|_| rng2.next_u64()).collect();
2770
2771 assert_ne!(v1, v2);
2772 }
2773
2774 #[test]
2775 fn test_seeded_rng_normal_distribution() {
2776 let mut rng = SeededRng::new(42);
2777 let samples: Vec<f32> = (0..1000).map(|_| rng.next_normal()).collect();
2778
2779 let mean: f32 = samples.iter().sum::<f32>() / samples.len() as f32;
2781 assert!(mean.abs() < 0.1, "Normal mean too far from 0: {}", mean);
2782
2783 let variance: f32 =
2785 samples.iter().map(|x| (x - mean).powi(2)).sum::<f32>() / samples.len() as f32;
2786 let std_dev = variance.sqrt();
2787 assert!(
2788 (std_dev - 1.0).abs() < 0.15,
2789 "Normal std dev too far from 1: {}",
2790 std_dev
2791 );
2792 }
2793
2794 #[test]
2797 fn test_spectral_encode_decode_full() {
2798 let data: Vec<f32> = (0..64).map(|i| (i as f32 * 0.1).sin()).collect();
2799
2800 let encoder = SpectralEncoder::new(4);
2801 let fragments = encoder.encode_2d(&data, 8, 8).unwrap();
2802
2803 assert_eq!(fragments.len(), 4);
2804
2805 let mut decoder = SpectralDecoder::new(8, 8, 4);
2807 for frag in fragments {
2808 decoder.add_fragment(&frag).unwrap();
2809 }
2810
2811 let reconstructed = decoder.reconstruct();
2812
2813 let mse: f32 = data
2815 .iter()
2816 .zip(reconstructed.iter())
2817 .map(|(a, b)| (a - b).powi(2))
2818 .sum::<f32>()
2819 / data.len() as f32;
2820
2821 assert!(
2822 mse < 0.1,
2823 "Spectral full reconstruction MSE too high: {}",
2824 mse
2825 );
2826 }
2827
2828 #[test]
2829 fn test_spectral_partial_reconstruction() {
2830 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
2831
2832 let encoder = SpectralEncoder::new(8);
2833 let fragments = encoder.encode_2d(&data, 8, 8).unwrap();
2834
2835 let mut decoder = SpectralDecoder::new(8, 8, 8);
2837 decoder.add_fragment(&fragments[0]).unwrap();
2838 decoder.add_fragment(&fragments[1]).unwrap();
2839
2840 assert!(decoder.quality() > 0.0);
2841 assert!(decoder.can_reconstruct());
2842
2843 let reconstructed = decoder.reconstruct();
2844 assert_eq!(reconstructed.len(), 64);
2845 }
2846
2847 #[test]
2848 fn test_spectral_quality_improves() {
2849 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
2850
2851 let encoder = SpectralEncoder::new(8);
2852 let fragments = encoder.encode_2d(&data, 8, 8).unwrap();
2853
2854 let mut decoder = SpectralDecoder::new(8, 8, 8);
2855
2856 let mut prev_quality = 0.0;
2857 for frag in fragments {
2858 decoder.add_fragment(&frag).unwrap();
2859 let quality = decoder.quality();
2860 assert!(quality >= prev_quality, "Quality should not decrease");
2861 prev_quality = quality;
2862 }
2863 }
2864
2865 #[test]
2868 fn test_lrdf_encode_decode() {
2869 let rows = 8;
2871 let cols = 8;
2872 let u: Vec<f32> = (0..rows).map(|i| i as f32 + 1.0).collect();
2873 let v: Vec<f32> = (0..cols).map(|i| (i as f32 + 1.0) * 0.5).collect();
2874
2875 let mut data = vec![0.0f32; rows * cols];
2876 for i in 0..rows {
2877 for j in 0..cols {
2878 data[i * cols + j] = u[i] * v[j];
2879 }
2880 }
2881
2882 let encoder = LrdfEncoder::new(4).with_max_rank(8);
2883 let fragments = encoder.encode_2d(&data, rows, cols).unwrap();
2884
2885 assert_eq!(fragments.len(), 4);
2886
2887 let mut decoder = LrdfDecoder::new(rows, cols, 4);
2888 for frag in fragments {
2889 decoder.add_fragment(&frag).unwrap();
2890 }
2891
2892 let reconstructed = decoder.reconstruct();
2893
2894 let mse: f32 = data
2896 .iter()
2897 .zip(reconstructed.iter())
2898 .map(|(a, b)| (a - b).powi(2))
2899 .sum::<f32>()
2900 / data.len() as f32;
2901
2902 assert!(mse < 1.0, "LRDF reconstruction MSE too high: {}", mse);
2903 }
2904
2905 #[test]
2906 fn test_lrdf_partial_reconstruction() {
2907 let rows = 8;
2908 let cols = 8;
2909 let data: Vec<f32> = (0..rows * cols).map(|i| i as f32).collect();
2910
2911 let encoder = LrdfEncoder::new(8);
2912 let fragments = encoder.encode_2d(&data, rows, cols).unwrap();
2913
2914 let mut decoder = LrdfDecoder::new(rows, cols, 8);
2915 decoder.add_fragment(&fragments[0]).unwrap();
2916 decoder.add_fragment(&fragments[1]).unwrap();
2917
2918 assert_eq!(decoder.fragments_loaded(), 2);
2919 assert!(decoder.quality() > 0.0);
2920
2921 let reconstructed = decoder.reconstruct();
2922 assert_eq!(reconstructed.len(), rows * cols);
2923 }
2924
2925 #[test]
2928 fn test_rph_encode_decode() {
2929 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
2930
2931 let encoder = RphEncoder::new(8, 12345);
2932 let fragments = encoder.encode(&data).unwrap();
2933
2934 assert_eq!(fragments.len(), 8);
2935
2936 let mut decoder = RphDecoder::new(64, 8);
2937 for frag in &fragments {
2938 decoder.add_fragment(frag).unwrap();
2939 }
2940
2941 let reconstructed = decoder.reconstruct();
2942 assert_eq!(reconstructed.len(), 64);
2943
2944 assert!(decoder.quality() > 0.9);
2946 }
2947
2948 #[test]
2949 fn test_rph_deterministic() {
2950 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
2951
2952 let encoder1 = RphEncoder::new(4, 42);
2953 let encoder2 = RphEncoder::new(4, 42);
2954
2955 let fragments1 = encoder1.encode(&data).unwrap();
2956 let fragments2 = encoder2.encode(&data).unwrap();
2957
2958 for (f1, f2) in fragments1.iter().zip(fragments2.iter()) {
2959 assert_eq!(f1.data, f2.data, "RPH should be deterministic");
2960 }
2961 }
2962
2963 #[test]
2966 fn test_encoder_decoder_spectral_roundtrip() {
2967 let data: Vec<f32> = (0..64).map(|i| (i as f32 * 0.1).sin()).collect();
2968
2969 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
2970
2971 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
2972
2973 let mut decoder = HoloTensorDecoder::new(header);
2974 for frag in fragments {
2975 decoder.add_fragment(frag).unwrap();
2976 }
2977
2978 let reconstructed = decoder.reconstruct().unwrap();
2979 assert_eq!(reconstructed.len(), 64);
2980 }
2981
2982 #[test]
2983 fn test_encoder_decoder_lrdf_roundtrip() {
2984 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
2985
2986 let encoder = HoloTensorEncoder::new(HolographicEncoding::LowRankDistributed)
2987 .with_fragments(4)
2988 .with_seed(42);
2989
2990 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
2991
2992 let mut decoder = HoloTensorDecoder::new(header);
2993 for frag in fragments {
2994 decoder.add_fragment(frag).unwrap();
2995 }
2996
2997 let reconstructed = decoder.reconstruct().unwrap();
2998 assert_eq!(reconstructed.len(), 64);
2999 }
3000
3001 #[test]
3002 fn test_encoder_decoder_rph_roundtrip() {
3003 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3004
3005 let encoder = HoloTensorEncoder::new(HolographicEncoding::RandomProjection)
3006 .with_fragments(4)
3007 .with_seed(12345);
3008
3009 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3010
3011 let mut decoder = HoloTensorDecoder::new(header);
3012 for frag in fragments {
3013 decoder.add_fragment(frag).unwrap();
3014 }
3015
3016 assert!(decoder.can_reconstruct());
3017 let reconstructed = decoder.reconstruct().unwrap();
3018 assert_eq!(reconstructed.len(), 64);
3019 }
3020
3021 #[test]
3022 fn test_progressive_quality_tracking() {
3023 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3024
3025 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(8);
3026
3027 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3028
3029 let mut decoder = HoloTensorDecoder::new(header);
3030 assert_eq!(decoder.fragments_loaded(), 0);
3031
3032 for (i, frag) in fragments.into_iter().enumerate() {
3033 let quality = decoder.add_fragment(frag).unwrap();
3034 assert_eq!(decoder.fragments_loaded(), (i + 1) as u16);
3035 assert!(quality > 0.0);
3036 }
3037 }
3038
3039 #[test]
3040 fn test_encoder_with_builder() {
3041 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral)
3042 .with_fragments(16)
3043 .with_seed(999)
3044 .with_compression(CompressionAlgorithm::Zstd)
3045 .with_essential_ratio(0.2)
3046 .with_max_rank(32);
3047
3048 let data = vec![1.0f32; 64];
3049 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3050
3051 assert_eq!(header.total_fragments, 16);
3052 assert_eq!(header.seed, 999);
3053 assert_eq!(header.compression, CompressionAlgorithm::Zstd);
3054 assert_eq!(fragments.len(), 16);
3055 }
3056
3057 #[test]
3060 fn test_writer_reader_roundtrip() {
3061 use std::io::Cursor;
3062
3063 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3064
3065 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral)
3066 .with_fragments(4)
3067 .with_seed(12345);
3068
3069 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3070
3071 let mut buffer = Cursor::new(Vec::new());
3073 let mut writer = HoloTensorWriter::new(&mut buffer);
3074 let bytes_written = writer.write(&header, &fragments).unwrap();
3075
3076 assert!(bytes_written > 0);
3077
3078 buffer.set_position(0);
3080 let mut reader = HoloTensorReader::new(&mut buffer).unwrap();
3081
3082 assert_eq!(reader.header().encoding, HolographicEncoding::Spectral);
3084 assert_eq!(reader.header().total_fragments, 4);
3085 assert_eq!(reader.header().seed, 12345);
3086
3087 let (read_header, read_fragments) = reader.read_all().unwrap();
3089 assert_eq!(read_header.total_fragments, 4);
3090 assert_eq!(read_fragments.len(), 4);
3091
3092 for (orig, read) in fragments.iter().zip(read_fragments.iter()) {
3094 assert_eq!(orig.index, read.index);
3095 assert_eq!(orig.checksum, read.checksum);
3096 assert_eq!(orig.data, read.data);
3097 }
3098 }
3099
3100 #[test]
3101 fn test_reader_progressive_loading() {
3102 use std::io::Cursor;
3103
3104 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3105
3106 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(8);
3107
3108 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3109
3110 let mut buffer = Cursor::new(Vec::new());
3112 let mut writer = HoloTensorWriter::new(&mut buffer);
3113 writer.write(&header, &fragments).unwrap();
3114
3115 buffer.set_position(0);
3117 let mut reader = HoloTensorReader::new(&mut buffer).unwrap();
3118
3119 for i in 0..8u16 {
3121 let frag = reader.read_fragment(i).unwrap();
3122 assert_eq!(frag.index, i);
3123 }
3124 }
3125
3126 #[test]
3127 fn test_read_to_quality() {
3128 use std::io::Cursor;
3129
3130 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3131
3132 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(8);
3133
3134 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3135
3136 let mut buffer = Cursor::new(Vec::new());
3138 let mut writer = HoloTensorWriter::new(&mut buffer);
3139 writer.write(&header, &fragments).unwrap();
3140
3141 buffer.set_position(0);
3143 let mut reader = HoloTensorReader::new(&mut buffer).unwrap();
3144 let (partial_fragments, quality) = reader.read_to_quality(0.75).unwrap();
3145
3146 assert!(!partial_fragments.is_empty());
3148 assert!(quality >= 0.75);
3149 assert!(partial_fragments.len() <= 8);
3151 }
3152
3153 #[test]
3154 fn test_fragment_index_entry_roundtrip() {
3155 let entry = FragmentIndexEntry {
3156 index: 42,
3157 flags: 0x1234,
3158 offset: 1024,
3159 compressed_size: 512,
3160 uncompressed_size: 1024,
3161 checksum: 0xDEADBEEF_CAFEBABE,
3162 };
3163
3164 let bytes = entry.to_bytes();
3165 let recovered = FragmentIndexEntry::from_bytes(&bytes);
3166
3167 assert_eq!(entry, recovered);
3168 }
3169
3170 #[test]
3171 fn test_writer_calculates_correct_size() {
3172 use std::io::Cursor;
3173
3174 let data: Vec<f32> = (0..16).map(|i| i as f32).collect();
3175
3176 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(2);
3177
3178 let (header, fragments) = encoder.encode_2d(&data, 4, 4).unwrap();
3179
3180 let mut buffer = Cursor::new(Vec::new());
3181 let mut writer = HoloTensorWriter::new(&mut buffer);
3182 let bytes_written = writer.write(&header, &fragments).unwrap();
3183
3184 let expected_header = HoloTensorHeader::BASE_SIZE;
3186 let expected_index = 2 * FragmentIndexEntry::SIZE;
3187 let expected_data: usize = fragments.iter().map(|f| f.data.len()).sum();
3188 let expected_total = expected_header + expected_index + expected_data;
3189
3190 assert_eq!(bytes_written as usize, expected_total);
3191 assert_eq!(buffer.get_ref().len(), expected_total);
3192 }
3193
3194 #[test]
3195 fn test_checksum_verification() {
3196 use std::io::Cursor;
3197
3198 let data: Vec<f32> = (0..16).map(|i| i as f32).collect();
3199
3200 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(2);
3201
3202 let (header, fragments) = encoder.encode_2d(&data, 4, 4).unwrap();
3203
3204 let mut buffer = Cursor::new(Vec::new());
3206 let mut writer = HoloTensorWriter::new(&mut buffer);
3207 writer.write(&header, &fragments).unwrap();
3208
3209 let inner = buffer.get_mut();
3211 let data_start = HoloTensorHeader::BASE_SIZE + 2 * FragmentIndexEntry::SIZE;
3212 if data_start < inner.len() {
3213 inner[data_start] ^= 0xFF;
3214 }
3215
3216 buffer.set_position(0);
3218 let mut reader = HoloTensorReader::new(&mut buffer).unwrap();
3219 let result = reader.read_fragment(0);
3220
3221 assert!(result.is_err());
3223 }
3224
3225 #[test]
3232 fn test_minimum_fragment_count_1() {
3233 let data: Vec<f32> = (0..64).map(|i| (i as f32 * 0.1).sin()).collect();
3234
3235 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(1);
3236
3237 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3238
3239 assert_eq!(header.total_fragments, 1);
3240 assert_eq!(fragments.len(), 1);
3241
3242 let mut decoder = HoloTensorDecoder::new(header);
3244 decoder.add_fragment(fragments[0].clone()).unwrap();
3245 let reconstructed = decoder.reconstruct().unwrap();
3246
3247 assert_eq!(reconstructed.len(), 64);
3248 }
3249
3250 #[test]
3251 fn test_minimum_fragment_count_2() {
3252 let data: Vec<f32> = (0..64).map(|i| (i as f32 * 0.1).sin()).collect();
3253
3254 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(2);
3255
3256 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3257
3258 assert_eq!(header.total_fragments, 2);
3259 assert_eq!(fragments.len(), 2);
3260
3261 let mut decoder = HoloTensorDecoder::new(header);
3263 for frag in fragments {
3264 decoder.add_fragment(frag).unwrap();
3265 }
3266 let reconstructed = decoder.reconstruct().unwrap();
3267
3268 assert_eq!(reconstructed.len(), 64);
3269 }
3270
3271 #[test]
3272 fn test_high_fragment_count_32() {
3273 let data: Vec<f32> = (0..256).map(|i| (i as f32 * 0.01).sin()).collect();
3274
3275 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(32);
3276
3277 let (header, fragments) = encoder.encode_2d(&data, 16, 16).unwrap();
3278
3279 assert_eq!(header.total_fragments, 32);
3280 assert_eq!(fragments.len(), 32);
3281
3282 let mut decoder = HoloTensorDecoder::new(header);
3284 for frag in fragments {
3285 decoder.add_fragment(frag).unwrap();
3286 }
3287 let reconstructed = decoder.reconstruct().unwrap();
3288
3289 assert_eq!(reconstructed.len(), 256);
3290
3291 let mse: f32 = data
3293 .iter()
3294 .zip(reconstructed.iter())
3295 .map(|(a, b)| (a - b).powi(2))
3296 .sum::<f32>()
3297 / data.len() as f32;
3298 assert!(mse < 0.01, "MSE {} too high for 32 fragments", mse);
3299 }
3300
3301 #[test]
3302 fn test_high_fragment_count_64() {
3303 let data: Vec<f32> = (0..1024).map(|i| (i as f32 * 0.001).sin()).collect();
3304
3305 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(64);
3306
3307 let (header, fragments) = encoder.encode_2d(&data, 32, 32).unwrap();
3308
3309 assert_eq!(header.total_fragments, 64);
3310 assert_eq!(fragments.len(), 64);
3311
3312 let mut decoder = HoloTensorDecoder::new(header);
3314 for frag in fragments {
3315 decoder.add_fragment(frag).unwrap();
3316 }
3317 let reconstructed = decoder.reconstruct().unwrap();
3318
3319 assert_eq!(reconstructed.len(), 1024);
3320 }
3321
3322 #[test]
3325 fn test_all_zeros_tensor() {
3326 let data = vec![0.0f32; 64];
3327
3328 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3329
3330 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3331
3332 let mut decoder = HoloTensorDecoder::new(header);
3333 for frag in fragments {
3334 decoder.add_fragment(frag).unwrap();
3335 }
3336 let reconstructed = decoder.reconstruct().unwrap();
3337
3338 for val in &reconstructed {
3340 assert!(val.abs() < 1e-5, "Expected near-zero, got {}", val);
3341 }
3342 }
3343
3344 #[test]
3345 fn test_constant_tensor() {
3346 let data = vec![42.0f32; 64];
3347
3348 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3349
3350 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3351
3352 let mut decoder = HoloTensorDecoder::new(header);
3353 for frag in fragments {
3354 decoder.add_fragment(frag).unwrap();
3355 }
3356 let reconstructed = decoder.reconstruct().unwrap();
3357
3358 let mse: f32 = data
3360 .iter()
3361 .zip(reconstructed.iter())
3362 .map(|(a, b)| (a - b).powi(2))
3363 .sum::<f32>()
3364 / data.len() as f32;
3365 assert!(mse < 0.1, "MSE {} too high for constant tensor", mse);
3366 }
3367
3368 #[test]
3369 fn test_negative_values_tensor() {
3370 let data: Vec<f32> = (0..64).map(|i| -(i as f32) - 100.0).collect();
3371
3372 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3373
3374 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3375
3376 let mut decoder = HoloTensorDecoder::new(header);
3377 for frag in fragments {
3378 decoder.add_fragment(frag).unwrap();
3379 }
3380 let reconstructed = decoder.reconstruct().unwrap();
3381
3382 assert_eq!(reconstructed.len(), 64);
3384 let avg: f32 = reconstructed.iter().sum::<f32>() / reconstructed.len() as f32;
3386 assert!(avg < 0.0, "Average should be negative, got {}", avg);
3387 }
3388
3389 #[test]
3390 fn test_mixed_sign_tensor() {
3391 let data: Vec<f32> = (0..64)
3392 .map(|i| if i % 2 == 0 { i as f32 } else { -(i as f32) })
3393 .collect();
3394
3395 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3396
3397 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3398
3399 let mut decoder = HoloTensorDecoder::new(header);
3400 for frag in fragments {
3401 decoder.add_fragment(frag).unwrap();
3402 }
3403 let reconstructed = decoder.reconstruct().unwrap();
3404
3405 assert_eq!(reconstructed.len(), 64);
3406 }
3407
3408 #[test]
3409 fn test_very_small_values() {
3410 let data: Vec<f32> = (0..64).map(|i| (i as f32 * 1e-6).sin() * 1e-6).collect();
3411
3412 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3413
3414 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3415
3416 let mut decoder = HoloTensorDecoder::new(header);
3417 for frag in fragments {
3418 decoder.add_fragment(frag).unwrap();
3419 }
3420 let reconstructed = decoder.reconstruct().unwrap();
3421
3422 assert_eq!(reconstructed.len(), 64);
3424 }
3425
3426 #[test]
3427 fn test_very_large_values() {
3428 let data: Vec<f32> = (0..64).map(|i| (i as f32 + 1.0) * 1e6).collect();
3429
3430 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3431
3432 let (header, fragments) = encoder.encode_2d(&data, 8, 8).unwrap();
3433
3434 let mut decoder = HoloTensorDecoder::new(header);
3435 for frag in fragments {
3436 decoder.add_fragment(frag).unwrap();
3437 }
3438 let reconstructed = decoder.reconstruct().unwrap();
3439
3440 assert_eq!(reconstructed.len(), 64);
3442 let max_orig = data.iter().fold(0.0f32, |a, &b| a.max(b.abs()));
3444 let max_err = data
3445 .iter()
3446 .zip(reconstructed.iter())
3447 .map(|(a, b)| (a - b).abs())
3448 .fold(0.0f32, f32::max);
3449 let relative_err = max_err / max_orig;
3450 assert!(
3451 relative_err < 0.1,
3452 "Relative error {} too high",
3453 relative_err
3454 );
3455 }
3456
3457 #[test]
3460 fn test_large_tensor_4k_elements() {
3461 let size = 64 * 64; let data: Vec<f32> = (0..size).map(|i| (i as f32 * 0.001).sin()).collect();
3463
3464 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(8);
3465
3466 let (header, fragments) = encoder.encode_2d(&data, 64, 64).unwrap();
3467
3468 let mut decoder = HoloTensorDecoder::new(header);
3469 for frag in fragments {
3470 decoder.add_fragment(frag).unwrap();
3471 }
3472 let reconstructed = decoder.reconstruct().unwrap();
3473
3474 assert_eq!(reconstructed.len(), size);
3475 }
3476
3477 #[test]
3478 fn test_large_tensor_16k_elements() {
3479 let width = 128;
3480 let height = 128;
3481 let size = width * height; let data: Vec<f32> = (0..size).map(|i| (i as f32 * 0.0001).sin()).collect();
3483
3484 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(8);
3485
3486 let (header, fragments) = encoder.encode_2d(&data, width, height).unwrap();
3487
3488 let mut decoder = HoloTensorDecoder::new(header);
3489 for frag in fragments {
3490 decoder.add_fragment(frag).unwrap();
3491 }
3492 let reconstructed = decoder.reconstruct().unwrap();
3493
3494 assert_eq!(reconstructed.len(), size);
3495 }
3496
3497 #[test]
3498 fn test_large_tensor_65k_elements() {
3499 let width = 256;
3500 let height = 256;
3501 let size = width * height; let data: Vec<f32> = (0..size).map(|i| (i as f32 * 0.00001).sin()).collect();
3503
3504 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(8);
3505
3506 let (header, fragments) = encoder.encode_2d(&data, width, height).unwrap();
3507
3508 let mut decoder = HoloTensorDecoder::new(header);
3509 for frag in fragments {
3510 decoder.add_fragment(frag).unwrap();
3511 }
3512 let reconstructed = decoder.reconstruct().unwrap();
3513
3514 assert_eq!(reconstructed.len(), size);
3515 }
3516
3517 #[test]
3520 fn test_quality_curve_extrapolation_beyond_sufficient() {
3521 let curve = QualityCurve::default();
3522
3523 let q_beyond = curve.predict(100, 8);
3525 assert!(
3526 (q_beyond - 1.0).abs() < 0.01,
3527 "Quality beyond sufficient should be 1.0, got {}",
3528 q_beyond
3529 );
3530 }
3531
3532 #[test]
3533 fn test_quality_curve_zero_fragments() {
3534 let curve = QualityCurve::default();
3535
3536 let q_zero = curve.predict(0, 8);
3538 assert_eq!(q_zero, 0.0, "Zero fragments should give zero quality");
3539 }
3540
3541 #[test]
3542 fn test_quality_curve_interpolation_smooth() {
3543 let curve = QualityCurve::default();
3544
3545 let mut prev_q = 0.0;
3547 for n in 0..=8 {
3548 let q = curve.predict(n, 8);
3549 assert!(
3550 q >= prev_q,
3551 "Quality should not decrease: f({}) = {} < prev {}",
3552 n,
3553 q,
3554 prev_q
3555 );
3556 prev_q = q;
3557 }
3558 }
3559
3560 #[test]
3561 fn test_quality_curve_fragments_for_quality_bounds() {
3562 let curve = QualityCurve::linear();
3563
3564 let min_frags = curve.fragments_for_quality(0.0, 8);
3566 assert!(
3567 min_frags <= 1,
3568 "Quality 0.0 should need at most 1 fragment, got {}",
3569 min_frags
3570 );
3571
3572 assert_eq!(curve.fragments_for_quality(1.0, 8), 8);
3574
3575 assert_eq!(curve.fragments_for_quality(2.0, 8), 8);
3577 }
3578
3579 #[test]
3582 fn test_wide_tensor_128x32() {
3583 let width = 128;
3584 let height = 32;
3585 let data: Vec<f32> = (0..width * height)
3586 .map(|i| (i as f32 * 0.01).sin())
3587 .collect();
3588
3589 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3590
3591 let (header, fragments) = encoder.encode_2d(&data, width, height).unwrap();
3592
3593 let mut decoder = HoloTensorDecoder::new(header);
3594 for frag in fragments {
3595 decoder.add_fragment(frag).unwrap();
3596 }
3597 let reconstructed = decoder.reconstruct().unwrap();
3598
3599 assert_eq!(reconstructed.len(), width * height);
3600 }
3601
3602 #[test]
3603 fn test_tall_tensor_32x128() {
3604 let width = 32;
3605 let height = 128;
3606 let data: Vec<f32> = (0..width * height)
3607 .map(|i| (i as f32 * 0.01).sin())
3608 .collect();
3609
3610 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3611
3612 let (header, fragments) = encoder.encode_2d(&data, width, height).unwrap();
3613
3614 let mut decoder = HoloTensorDecoder::new(header);
3615 for frag in fragments {
3616 decoder.add_fragment(frag).unwrap();
3617 }
3618 let reconstructed = decoder.reconstruct().unwrap();
3619
3620 assert_eq!(reconstructed.len(), width * height);
3621 }
3622
3623 #[test]
3624 fn test_prime_dimension_tensor() {
3625 let width = 97;
3627 let height = 89;
3628 let data: Vec<f32> = (0..width * height)
3629 .map(|i| (i as f32 * 0.01).sin())
3630 .collect();
3631
3632 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(4);
3633
3634 let (header, fragments) = encoder.encode_2d(&data, width, height).unwrap();
3635
3636 let mut decoder = HoloTensorDecoder::new(header);
3637 for frag in fragments {
3638 decoder.add_fragment(frag).unwrap();
3639 }
3640 let reconstructed = decoder.reconstruct().unwrap();
3641
3642 assert_eq!(reconstructed.len(), width * height);
3643 }
3644
3645 #[test]
3648 fn test_encoding_deterministic_same_seed() {
3649 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3650
3651 let encoder1 = HoloTensorEncoder::new(HolographicEncoding::Spectral)
3652 .with_fragments(4)
3653 .with_seed(12345);
3654
3655 let encoder2 = HoloTensorEncoder::new(HolographicEncoding::Spectral)
3656 .with_fragments(4)
3657 .with_seed(12345);
3658
3659 let (_, fragments1) = encoder1.encode_2d(&data, 8, 8).unwrap();
3660 let (_, fragments2) = encoder2.encode_2d(&data, 8, 8).unwrap();
3661
3662 for (f1, f2) in fragments1.iter().zip(fragments2.iter()) {
3663 assert_eq!(f1.data, f2.data, "Encoding should be deterministic");
3664 }
3665 }
3666
3667 #[test]
3668 fn test_encoding_different_seeds_different_output() {
3669 let data: Vec<f32> = (0..64).map(|i| i as f32).collect();
3670
3671 let encoder1 = HoloTensorEncoder::new(HolographicEncoding::RandomProjection)
3674 .with_fragments(4)
3675 .with_seed(1);
3676
3677 let encoder2 = HoloTensorEncoder::new(HolographicEncoding::RandomProjection)
3678 .with_fragments(4)
3679 .with_seed(2);
3680
3681 let (_, fragments1) = encoder1.encode_2d(&data, 8, 8).unwrap();
3682 let (_, fragments2) = encoder2.encode_2d(&data, 8, 8).unwrap();
3683
3684 let any_different = fragments1
3686 .iter()
3687 .zip(fragments2.iter())
3688 .any(|(f1, f2)| f1.data != f2.data);
3689 assert!(
3690 any_different,
3691 "Different seeds should produce different output"
3692 );
3693 }
3694
3695 #[test]
3698 fn test_encode_mismatched_dimensions() {
3699 let data = vec![1.0f32; 100]; let encoder = SpectralEncoder::new(4);
3702
3703 let result = encoder.encode_2d(&data, 8, 8);
3706 assert!(result.is_err(), "Should error on dimension mismatch");
3707 }
3708
3709 #[test]
3710 fn test_decode_no_fragments() {
3711 let decoder = SpectralDecoder::new(8, 8, 4);
3713
3714 let reconstructed = decoder.reconstruct();
3716 assert!(
3717 reconstructed.iter().all(|&x| x == 0.0),
3718 "Empty decoder should return zeros"
3719 );
3720 }
3721
3722 #[test]
3723 fn test_decode_corrupted_fragment_data() {
3724 let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
3726 let encoder = SpectralEncoder::new(4);
3727 let mut fragments = encoder.encode_2d(&data, 8, 8).unwrap();
3728
3729 if !fragments.is_empty() {
3731 fragments[0].data = vec![0; 4]; }
3733
3734 let mut decoder = SpectralDecoder::new(8, 8, 4);
3736 let result = decoder.add_fragment(&fragments[0]);
3737 let _ = result;
3739 }
3740
3741 #[test]
3742 fn test_encode_single_element() {
3743 let data = vec![42.0f32];
3745 let encoder = SpectralEncoder::new(4);
3746
3747 let result = encoder.encode_2d(&data, 1, 1);
3748 if let Ok(fragments) = result {
3750 let mut decoder = SpectralDecoder::new(1, 1, 4);
3751 for frag in &fragments {
3752 let _ = decoder.add_fragment(frag);
3753 }
3754 let reconstructed = decoder.reconstruct();
3755 assert_eq!(reconstructed.len(), 1);
3756 }
3757 }
3758
3759 #[test]
3760 fn test_file_operations_invalid_path() {
3761 let result = open_holotensor("/this/path/does/not/exist/ever.holo");
3763 assert!(result.is_err(), "Should error on non-existent file");
3764 }
3765
3766 #[test]
3767 fn test_quality_curve_default() {
3768 let curve = QualityCurve::default();
3769
3770 assert!(curve.min_fragments > 0 || curve.sufficient_fragments > 0);
3772 }
3773
3774 #[test]
3782 fn test_very_high_fragment_count() {
3783 let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
3784
3785 let encoder100 = SpectralEncoder::new(100);
3787 let result100 = encoder100.encode_2d(&data, 8, 8);
3788 assert!(result100.is_ok(), "Should handle high fragment count");
3790 }
3791
3792 #[test]
3793 fn test_minimum_valid_fragment_count() {
3794 let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
3795
3796 let encoder1 = SpectralEncoder::new(1);
3798 let result1 = encoder1.encode_2d(&data, 8, 8);
3799 assert!(result1.is_ok(), "Should handle 1 fragment");
3800 assert_eq!(result1.unwrap().len(), 1);
3801 }
3802
3803 #[test]
3804 fn test_full_reconstruction_quality() {
3805 let data: Vec<f32> = (0..64).map(|i| (i as f32 * 0.1).sin()).collect();
3807 let encoder = SpectralEncoder::new(4);
3808 let fragments = encoder.encode_2d(&data, 8, 8).unwrap();
3809
3810 let mut decoder = SpectralDecoder::new(8, 8, 4);
3811 for frag in &fragments {
3812 decoder.add_fragment(frag).unwrap();
3813 }
3814
3815 let reconstructed = decoder.reconstruct();
3816 let mse: f32 = data
3817 .iter()
3818 .zip(reconstructed.iter())
3819 .map(|(a, b)| (a - b).powi(2))
3820 .sum::<f32>()
3821 / data.len() as f32;
3822
3823 assert!(
3824 mse < 1.0,
3825 "Full reconstruction should have reasonable MSE, got {}",
3826 mse
3827 );
3828 }
3829
3830 #[test]
3831 fn test_decoder_quality_estimate() {
3832 let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
3833 let encoder = SpectralEncoder::new(4);
3834 let fragments = encoder.encode_2d(&data, 8, 8).unwrap();
3835
3836 let mut decoder = SpectralDecoder::new(8, 8, 4);
3837
3838 assert!(decoder.quality() >= 0.0);
3840
3841 let mut prev_quality = 0.0;
3843 for frag in &fragments {
3844 decoder.add_fragment(frag).unwrap();
3845 let quality = decoder.quality();
3846 assert!(
3847 quality >= prev_quality - 0.001, "Quality should not decrease significantly"
3849 );
3850 prev_quality = quality;
3851 }
3852 }
3853
3854 #[test]
3855 fn test_decoder_can_reconstruct_flag() {
3856 let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
3857 let encoder = SpectralEncoder::new(4);
3858 let fragments = encoder.encode_2d(&data, 8, 8).unwrap();
3859
3860 let mut decoder = SpectralDecoder::new(8, 8, 4);
3861
3862 assert!(
3864 !decoder.can_reconstruct(),
3865 "Should not be able to reconstruct with 0 fragments"
3866 );
3867
3868 decoder.add_fragment(&fragments[0]).unwrap();
3870 assert!(
3871 decoder.can_reconstruct(),
3872 "Should be able to reconstruct with 1 fragment"
3873 );
3874
3875 for frag in &fragments[1..] {
3877 decoder.add_fragment(frag).unwrap();
3878 assert!(decoder.can_reconstruct());
3879 }
3880 }
3881
3882 #[test]
3885 fn test_encode_1d_preserves_original_shape() {
3886 let data: Vec<f32> = (0..576).map(|i| i as f32 * 0.01).collect();
3888
3889 let encoder =
3891 HoloTensorEncoder::new(HolographicEncoding::LowRankDistributed).with_fragments(4);
3892 let (header, _fragments) = encoder.encode_1d(&data).unwrap();
3893
3894 assert_eq!(
3896 header.shape,
3897 vec![576],
3898 "1D tensor shape should be [576], got {:?}",
3899 header.shape
3900 );
3901 }
3902
3903 #[test]
3904 fn test_encode_decode_1d_roundtrip_shape() {
3905 let data: Vec<f32> = (0..256).map(|i| (i as f32).sin()).collect();
3907
3908 let encoder =
3910 HoloTensorEncoder::new(HolographicEncoding::LowRankDistributed).with_fragments(4);
3911 let (header, fragments) = encoder.encode_1d(&data).unwrap();
3912
3913 let mut decoder = HoloTensorDecoder::new(header.clone());
3914 for frag in fragments {
3915 decoder.add_fragment(frag).unwrap();
3916 }
3917 let reconstructed = decoder.reconstruct().unwrap();
3918
3919 assert_eq!(header.shape, vec![256]);
3921 assert_eq!(reconstructed.len(), 256);
3922 }
3923
3924 #[test]
3925 fn test_encode_1d_all_encodings_preserve_shape() {
3926 let data: Vec<f32> = (0..64).map(|i| i as f32 * 0.1).collect();
3927
3928 for encoding in [
3929 HolographicEncoding::Spectral,
3930 HolographicEncoding::RandomProjection,
3931 HolographicEncoding::LowRankDistributed,
3932 ] {
3933 let encoder = HoloTensorEncoder::new(encoding)
3934 .with_fragments(4)
3935 .with_seed(42);
3936 let (header, _fragments) = encoder.encode_1d(&data).unwrap();
3937
3938 assert_eq!(
3939 header.shape,
3940 vec![64],
3941 "1D tensor shape should be [64] for {:?}, got {:?}",
3942 encoding,
3943 header.shape
3944 );
3945 }
3946 }
3947
3948 #[test]
3949 fn test_encode_nd_preserves_arbitrary_shape() {
3950 let data: Vec<f32> = vec![1.0; 24];
3952
3953 let encoder =
3954 HoloTensorEncoder::new(HolographicEncoding::LowRankDistributed).with_fragments(4);
3955
3956 let (header_1d, _) = encoder.encode_nd(&data[..8], &[8]).unwrap();
3958 assert_eq!(header_1d.shape, vec![8]);
3959
3960 let (header_2d, _) = encoder.encode_nd(&data[..24], &[4, 6]).unwrap();
3962 assert_eq!(header_2d.shape, vec![4, 6]);
3963
3964 let (header_3d, _) = encoder.encode_nd(&data[..24], &[2, 3, 4]).unwrap();
3966 assert_eq!(header_3d.shape, vec![2, 3, 4]);
3967 }
3968
3969 #[test]
3970 fn test_hct_file_roundtrip_preserves_1d_shape() {
3971 use std::io::Cursor;
3972
3973 let data: Vec<f32> = vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0];
3975 let encoder = HoloTensorEncoder::new(HolographicEncoding::Spectral).with_fragments(2);
3976 let (header, fragments) = encoder.encode_1d(&data).unwrap();
3977
3978 let mut buffer = Cursor::new(Vec::new());
3980 {
3981 let mut writer = HoloTensorWriter::new(&mut buffer);
3982 writer.write(&header, &fragments).unwrap();
3983 }
3984
3985 buffer.set_position(0);
3986 let mut reader = HoloTensorReader::new(buffer).unwrap();
3987 let (read_header, _) = reader.read_all().unwrap();
3988
3989 assert_eq!(
3991 read_header.shape,
3992 vec![8],
3993 "Shape after file roundtrip should be [8], got {:?}",
3994 read_header.shape
3995 );
3996 }
3997}
3998
3999#[cfg(test)]
4000mod dct_tests {
4001 use super::*;
4002
4003 fn max_error(a: &[f32], b: &[f32]) -> f32 {
4004 a.iter()
4005 .zip(b.iter())
4006 .map(|(x, y)| (x - y).abs())
4007 .fold(0.0f32, f32::max)
4008 }
4009
4010 #[test]
4011 fn test_dct_roundtrip_small() {
4012 for n in [4, 8, 16, 32] {
4013 let input: Vec<f32> = (0..n).map(|i| (i as f32 * 0.1).sin()).collect();
4014 let mut dct_out = vec![0.0f32; n];
4015 let mut reconstructed = vec![0.0f32; n];
4016
4017 dct_1d(&input, &mut dct_out);
4018 idct_1d(&dct_out, &mut reconstructed);
4019
4020 let err = max_error(&input, &reconstructed);
4021 assert!(err < 1e-5, "DCT roundtrip error {err} too high for n={n}");
4022 }
4023 }
4024
4025 #[test]
4026 fn test_dct_roundtrip_fft_sizes() {
4027 for n in [64, 128, 256, 512, 1024] {
4028 let input: Vec<f32> = (0..n).map(|i| (i as f32 * 0.1).sin()).collect();
4029 let mut dct_out = vec![0.0f32; n];
4030 let mut reconstructed = vec![0.0f32; n];
4031
4032 dct_1d(&input, &mut dct_out);
4033 idct_1d(&dct_out, &mut reconstructed);
4034
4035 let err = max_error(&input, &reconstructed);
4036 assert!(err < 1e-4, "DCT roundtrip error {err} too high for n={n}");
4037 }
4038 }
4039
4040 #[test]
4041 fn test_dct_roundtrip_neural_sizes() {
4042 for n in [576, 1536, 3584, 4096] {
4043 let input: Vec<f32> = (0..n).map(|i| (i as f32 * 0.01).sin() * 0.1).collect();
4044 let mut dct_out = vec![0.0f32; n];
4045 let mut reconstructed = vec![0.0f32; n];
4046
4047 dct_1d(&input, &mut dct_out);
4048 idct_1d(&dct_out, &mut reconstructed);
4049
4050 let err = max_error(&input, &reconstructed);
4051 assert!(err < 1e-4, "DCT roundtrip error {err} too high for n={n}");
4052 }
4053 }
4054
4055 #[test]
4056 fn test_dct_2d_roundtrip() {
4057 let width = 64;
4058 let height = 64;
4059 let input: Vec<f32> = (0..width * height)
4060 .map(|i| ((i as f32 * 0.01).sin() * 0.5))
4061 .collect();
4062 let mut dct_out = vec![0.0f32; width * height];
4063 let mut reconstructed = vec![0.0f32; width * height];
4064
4065 dct_2d(&input, &mut dct_out, width, height);
4066 idct_2d(&dct_out, &mut reconstructed, width, height);
4067
4068 let err = max_error(&input, &reconstructed);
4069 assert!(err < 1e-3, "2D DCT roundtrip error {err} too high");
4070 }
4071}