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