1#[macro_use]
2use crate::*;
3use super::*;
4use num_traits::*;
5#[cfg(feature = "matrix")]
6use mech_core::matrix::Matrix;
7use std::ops::DivAssign;
8
9#[macro_export]
14macro_rules! impl_div_assign_match_arms {
15 ($fxn_name:ident,$macro_name:ident, $arg:expr) => {
16 paste!{
17 [<impl_set_ $macro_name _match_arms>]!(
18 $fxn_name,
19 $arg,
20 U8, "u8";
21 U16, "u16";
22 U32, "u32";
23 U64, "u64";
24 U128, "u128";
25 I8, "i8";
26 I16, "i16";
27 I32, "i32";
28 I64, "i64";
29 U128, "u128";
30 F32, "f32";
31 F64, "f64" ;
32 C64, "complex";
33 R64, "rational";
34 )
35 }
36 }
37}
38
39#[cfg(feature = "matrix")]
40macro_rules! impl_div_assign_range_fxn_s {
41 ($struct_name:ident, $op:ident, $ix:ty) => {
42 impl_op_assign_range_fxn_s!($struct_name, $op, $ix);
43 }
44}
45
46#[cfg(feature = "matrix")]
47macro_rules! impl_div_assign_range_fxn_v {
48 ($struct_name:ident, $op:ident, $ix:ty) => {
49 impl_op_assign_range_fxn_v!($struct_name, $op, $ix);
50 }
51}
52
53impl_assign_scalar_scalar!(Div, /=);
56impl_assign_vector_vector!(Div, /=);
57impl_assign_vector_scalar!(Div, /=);
58fn div_assign_value_fxn(sink: Value, source: Value) -> MResult<Box<dyn MechFunction>> {
59 impl_op_assign_value_match_arms!(
60 Div,
61 (sink, source),
62 U8, "u8";
63 U16, "u16";
64 U32, "u32";
65 U64, "u64";
66 U128, "u128";
67 I8, "i8";
68 I16, "i16";
69 I32, "i32";
70 I64, "i64";
71 U128, "u128";
72 F32, "f32";
73 F64, "f64";
74 R64, "rational";
75 C64, "complex";
76 )
77}
78
79pub struct DivAssignValue {}
80impl NativeFunctionCompiler for DivAssignValue {
81 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
82 if arguments.len() <= 1 {
83 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() },None).with_compiler_loc());
84 }
85 let sink = arguments[0].clone();
86 let source = arguments[1].clone();
87 match div_assign_value_fxn(sink.clone(),source.clone()) {
88 Ok(fxn) => Ok(fxn),
89 Err(x) => {
90 match (sink,source) {
91 (Value::MutableReference(sink),Value::MutableReference(source)) => { div_assign_value_fxn(sink.borrow().clone(),source.borrow().clone()) },
92 (sink,Value::MutableReference(source)) => { div_assign_value_fxn(sink.clone(),source.borrow().clone()) },
93 (Value::MutableReference(sink),source) => { div_assign_value_fxn(sink.borrow().clone(),source.clone()) },
94 (arg1,arg2) => Err(MechError2::new(
95 UnhandledFunctionArgumentKind2 { arg: (arg1.kind(),arg2.kind()), fxn_name: "math/div-assign".to_string() },
96 None
97 ).with_compiler_loc()
98 ),
99 }
100 }
101 }
102 }
103}
104
105register_descriptor! {
106 FunctionCompilerDescriptor {
107 name: "math/div-assign",
108 ptr: &DivAssignValue{},
109 }
110}
111
112macro_rules! div_assign_1d_range {
115 ($source:expr, $ix:expr, $sink:expr) => {
116 unsafe {
117 for i in 0..($ix).len() {
118 ($sink)[($ix)[i] - 1] /= *($source);
119 }
120 }
121 };}
122
123macro_rules! div_assign_1d_range_b {
124 ($source:expr, $ix:expr, $sink:expr) => {
125 unsafe {
126 for i in 0..($ix).len() {
127 if $ix[i] == true {
128 ($sink)[i] /= *($source);
129 }
130 }
131 }
132 };}
133
134macro_rules! div_assign_1d_range_vec {
135 ($source:expr, $ix:expr, $sink:expr) => {
136 unsafe {
137 for i in 0..($ix).len() {
138 ($sink)[($ix)[i] - 1] /= ($source)[i];
139 }
140 }
141 };}
142
143macro_rules! div_assign_1d_range_vec_b {
144 ($source:expr, $ix:expr, $sink:expr) => {
145 unsafe {
146 for i in 0..($ix).len() {
147 if $ix[i] == true {
148 ($sink)[i] /= ($source)[i];
149 }
150 }
151 }
152 };}
153
154#[cfg(feature = "matrix")]
155impl_div_assign_range_fxn_s!(DivAssign1DRS,div_assign_1d_range,usize);
156#[cfg(feature = "matrix")]
157impl_div_assign_range_fxn_s!(DivAssign1DRB,div_assign_1d_range_b,bool);
158#[cfg(feature = "matrix")]
159impl_div_assign_range_fxn_v!(DivAssign1DRV,div_assign_1d_range_vec,usize);
160#[cfg(feature = "matrix")]
161impl_div_assign_range_fxn_v!(DivAssign1DRVB,div_assign_1d_range_vec_b,bool);
162
163op_assign_range_fxn!(div_assign_range_fxn, DivAssign1DR);
164
165pub struct DivAssignRange {}
166impl NativeFunctionCompiler for DivAssignRange {
167 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
168 if arguments.len() <= 1 {
169 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() },None).with_compiler_loc());
170 }
171 let sink: Value = arguments[0].clone();
172 let source: Value = arguments[1].clone();
173 let ixes = arguments.clone().split_off(2);
174 match div_assign_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
175 Ok(fxn) => Ok(fxn),
176 Err(x) => {
177 match (&sink, &ixes, &source) {
178 (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { div_assign_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
179 (sink,ixes,Value::MutableReference(source)) => { div_assign_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
180 (Value::MutableReference(sink),ixes,source) => { div_assign_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
181 x => Err(MechError2::new(
182 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "math/div-assign/range".to_string() },
183 None
184 ).with_compiler_loc()
185 ),
186 }
187 }
188 }
189 }
190}
191
192register_descriptor! {
193 FunctionCompilerDescriptor {
194 name: "math/div-assign/range",
195 ptr: &DivAssignRange{},
196 }
197}
198
199macro_rules! div_assign_2d_vector_all {
203 ($source:expr, $ix:expr, $sink:expr) => {
204 for val in ($sink).iter_mut() {
205 *val /= (*$source);
206 }
207 };}
208
209macro_rules! div_assign_2d_vector_all_b {
210 ($source:expr, $ix:expr, $sink:expr) => {
211 let ncols = ($sink).ncols();
212 for (i, val) in ($sink).iter_mut().enumerate() {
213 let row = i / ncols;
214 if $ix[row] {
215 *val /= *($source);
216 }
217 }
218 };}
219
220macro_rules! div_assign_2d_vector_all_mat {
221 ($source:expr, $ix:expr, $sink:expr) => {
222 {
223 let nsrc = $source.nrows();
224 for (i, &rix) in $ix.iter().enumerate() {
225 let row_index = rix - 1;
226 let mut sink_row = $sink.row_mut(row_index);
227 let src_row = $source.row(i % nsrc); for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
229 *dst /= *src;
230 }
231 }
232 }
233 };}
234
235macro_rules! div_assign_2d_vector_all_mat_b {
236 ($source:expr, $ix:expr, $sink:expr) => {
237 {
238 let mut src_i = 0;
239 for (i, rix) in (&$ix).iter().enumerate() {
240 if *rix == true {
241 let mut sink_row = ($sink).row_mut(i);
242 let src_row = ($source).row(src_i);
243 for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
244 *dst /= *src;
245 }
246 src_i += 1;
247 }
248 }
249 }
250 };}
251
252#[cfg(feature = "matrix")]
253impl_div_assign_range_fxn_s!(DivAssign2DRAS,div_assign_2d_vector_all,usize);
254#[cfg(feature = "matrix")]
255impl_div_assign_range_fxn_s!(DivAssign2DRASB,div_assign_2d_vector_all_b,bool);
256#[cfg(feature = "matrix")]
257impl_div_assign_range_fxn_v!(DivAssign2DRAV,div_assign_2d_vector_all_mat,usize);
258#[cfg(feature = "matrix")]
259impl_div_assign_range_fxn_v!(DivAssign2DRAVB,div_assign_2d_vector_all_mat_b,bool);
260
261op_assign_range_all_fxn!(div_assign_range_all_fxn, DivAssign2DRA);
262
263pub struct DivAssignRangeAll {}
264impl NativeFunctionCompiler for DivAssignRangeAll {
265 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
266 if arguments.len() <= 1 {
267 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() },None).with_compiler_loc());
268 }
269 let sink: Value = arguments[0].clone();
270 let source: Value = arguments[1].clone();
271 let ixes = arguments.clone().split_off(2);
272 match div_assign_range_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
273 Ok(fxn) => Ok(fxn),
274 Err(_) => {
275 match (&sink,&ixes,&source) {
276 (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { div_assign_range_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
277 (sink,ixes,Value::MutableReference(source)) => { div_assign_range_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
278 (Value::MutableReference(sink),ixes,source) => { div_assign_range_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
279 _ => Err(MechError2::new(
280 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "math/div-assign/range-all".to_string() },
281 None
282 ).with_compiler_loc()
283 ),
284 }
285 }
286 }
287 }
288}
289
290register_descriptor! {
291 FunctionCompilerDescriptor {
292 name: "math/div-assign/range-all",
293 ptr: &DivAssignRangeAll{},
294 }
295}