rgsl/types/
multiset.rs

1//
2// A rust binding for the GSL library by Guillaume Gomez (guillaume1.gomez@gmail.com)
3//
4
5/*!
6# Multisets
7
8This chapter describes functions for creating and manipulating multisets. A multiset c is represented by an array of k integers in the
9range 0 to n-1, where each value c_i may occur more than once. The multiset c corresponds to indices of k elements chosen from an n element
10vector with replacement. In mathematical terms, n is the cardinality of the multiset while k is the maximum multiplicity of any value.
11Multisets are useful, for example, when iterating over the indices of a k-th order symmetric tensor in n-space.
12!*/
13
14use crate::Value;
15use ffi::FFI;
16use std::io;
17
18ffi_wrapper!(MultiSet, *mut sys::gsl_multiset, gsl_multiset_free);
19
20impl MultiSet {
21    /// This function allocates memory for a new multiset with parameters n, k. The multiset is not
22    /// initialized and its elements are undefined. Use the function [`Self::new_with_init`] if you
23    /// want to create a multiset which is initialized to the lexicographically first multiset
24    /// element. A null pointer is returned if insufficient memory is available to create the
25    /// multiset.
26    #[doc(alias = "gsl_multiset_alloc")]
27    pub fn new(n: usize, k: usize) -> Option<Self> {
28        let tmp = unsafe { sys::gsl_multiset_alloc(n, k) };
29
30        if tmp.is_null() {
31            None
32        } else {
33            Some(Self::wrap(tmp))
34        }
35    }
36
37    /// This function allocates memory for a new multiset with parameters n, k and initializes it to
38    /// the lexicographically first multiset element. A null pointer is returned if insufficient
39    /// memory is available to create the multiset.
40    #[doc(alias = "gsl_multiset_calloc")]
41    pub fn new_with_init(n: usize, k: usize) -> Option<Self> {
42        let tmp = unsafe { sys::gsl_multiset_calloc(n, k) };
43
44        if tmp.is_null() {
45            None
46        } else {
47            Some(Self::wrap(tmp))
48        }
49    }
50
51    /// This function initializes the multiset c to the lexicographically first multiset element,
52    /// i.e. 0 repeated k times.
53    #[doc(alias = "gsl_multiset_init_first")]
54    pub fn init_first(&mut self) {
55        unsafe { sys::gsl_multiset_init_first(self.unwrap_unique()) }
56    }
57
58    /// This function initializes the multiset c to the lexicographically last multiset element,
59    /// i.e. n-1 repeated k times.
60    #[doc(alias = "gsl_multiset_init_last")]
61    pub fn init_last(&mut self) {
62        unsafe { sys::gsl_multiset_init_last(self.unwrap_unique()) }
63    }
64
65    /// This function copies the elements of the multiset `self` into the multiset dest. The two
66    /// multisets must have the same size.
67    #[doc(alias = "gsl_multiset_memcpy")]
68    pub fn copy(&self, dest: &mut MultiSet) -> Result<(), Value> {
69        let ret = unsafe { sys::gsl_multiset_memcpy(dest.unwrap_unique(), self.unwrap_shared()) };
70        result_handler!(ret, ())
71    }
72
73    /// This function returns the value of the i-th element of the multiset c. If i lies outside the
74    /// allowed range of 0 to k-1 then the error handler is invoked and 0 is returned.
75    #[doc(alias = "gsl_multiset_get")]
76    pub fn get(&self, i: usize) -> usize {
77        unsafe { sys::gsl_multiset_get(self.unwrap_shared(), i) }
78    }
79
80    /// This function returns the range (n) of the multiset `self`.
81    #[doc(alias = "gsl_multiset_n")]
82    pub fn n(&self) -> usize {
83        unsafe { sys::gsl_multiset_n(self.unwrap_shared()) }
84    }
85
86    /// This function returns the number of elements (k) in the multiset `self`.
87    #[doc(alias = "gsl_multiset_k")]
88    pub fn k(&self) -> usize {
89        unsafe { sys::gsl_multiset_k(self.unwrap_shared()) }
90    }
91
92    /// This function returns a pointer to the array of elements in the multiset `self`.
93    #[doc(alias = "gsl_multiset_data")]
94    pub fn data(&self) -> &[usize] {
95        unsafe {
96            let ptr = sys::gsl_multiset_data(self.unwrap_shared());
97            std::slice::from_raw_parts(ptr, self.k())
98        }
99    }
100
101    /// This function returns a pointer to the array of elements in the multiset `self`.
102    // checker:ignore
103    #[doc(alias = "gsl_multiset_data")]
104    pub fn data_mut(&mut self) -> &mut [usize] {
105        unsafe {
106            let ptr = sys::gsl_multiset_data(self.unwrap_shared());
107            std::slice::from_raw_parts_mut(ptr, self.k())
108        }
109    }
110
111    /// This function checks that the multiset self is valid. The k elements should lie in the range
112    /// 0 to n-1, with each value occurring in non-decreasing order.
113    ///
114    /// Returns `OK(())` if valid.
115    #[doc(alias = "gsl_multiset_valid")]
116    pub fn valid(&self) -> Result<(), Value> {
117        // Little trick here: the function is expecting a mutable pointer whereas it doesn't need
118        // to be...
119        let ret = unsafe { sys::gsl_multiset_valid(self.inner) };
120        result_handler!(ret, ())
121    }
122
123    /// This function advances the multiset self to the next multiset element in lexicographic order
124    /// and returns `Ok(())`. If no further multisets elements are available it returns
125    /// [`Err(Value::Failure)`](Value::Failure) and leaves self unmodified. Starting with the first
126    /// multiset and repeatedly applying this function will iterate through all possible multisets
127    /// of a given order.
128    #[doc(alias = "gsl_multiset_next")]
129    pub fn next(&mut self) -> Result<(), Value> {
130        let ret = unsafe { sys::gsl_multiset_next(self.unwrap_unique()) };
131        result_handler!(ret, ())
132    }
133
134    /// This function steps backwards from the multiset self to the previous multiset element in
135    /// lexicographic order, returning [`Value::Success`]. If no previous multiset is available it
136    /// returns [`Value::Failure`] and leaves self unmodified.
137    #[doc(alias = "gsl_multiset_prev")]
138    pub fn prev(&mut self) -> Result<(), Value> {
139        let ret = unsafe { sys::gsl_multiset_prev(self.unwrap_unique()) };
140        result_handler!(ret, ())
141    }
142
143    pub fn print<W: io::Write>(&self, writer: &mut W) -> io::Result<()> {
144        write!(writer, "{:?}", self.data())
145    }
146}