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_add_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_add_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_add_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!(Add, +=);
53impl_assign_vector_vector!(Add, +=);
54impl_assign_vector_scalar!(Add, +=);
55
56pub fn add_assign_math_fxn(sink: Value, source: Value) -> MResult<Box<dyn MechFunction>> {
57 impl_op_assign_value_match_arms!(
58 Add,
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 AddAssignMath {}
78impl NativeFunctionCompiler for AddAssignMath {
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 add_assign_math_fxn(sink.clone(),source.clone()) {
86 Ok(fxn) => Ok(fxn),
87 Err(x) => {
88 match (sink,source) {
89 (Value::MutableReference(sink),Value::MutableReference(source)) => { add_assign_math_fxn(sink.borrow().clone(),source.borrow().clone()) },
90 (sink,Value::MutableReference(source)) => { add_assign_math_fxn(sink.clone(),source.borrow().clone()) },
91 (Value::MutableReference(sink),source) => { add_assign_math_fxn(sink.borrow().clone(),source.clone()) },
92 (arg1,arg2) => Err(MechError2::new(
93 UnhandledFunctionArgumentKind2 { arg: (arg1.kind(),arg2.kind()), fxn_name: "math/add-assign".to_string() },
94 None
95 ).with_compiler_loc()
96 ),
97 }
98 }
99 }
100 }
101}
102
103register_descriptor! {
104 FunctionCompilerDescriptor {
105 name: "math/add-assign",
106 ptr: &AddAssignMath{},
107 }
108}
109
110macro_rules! add_assign_1d_range {
113 ($source:expr, $ix:expr, $sink:expr) => {
114 unsafe {
115 for i in 0..($ix).len() {
116 ($sink)[($ix)[i] - 1] += ($source).clone();
117 }
118 }
119 };}
120
121macro_rules! add_assign_1d_range_b {
122 ($source:expr, $ix:expr, $sink:expr) => {
123 unsafe {
124 for i in 0..($ix).len() {
125 if $ix[i] == true {
126 ($sink)[i] += ($source).clone();
127 }
128 }
129 }
130 };}
131
132macro_rules! add_assign_1d_range_vec {
133 ($source:expr, $ix:expr, $sink:expr) => {
134 unsafe {
135 for i in 0..($ix).len() {
136 ($sink)[($ix)[i] - 1] += ($source)[i].clone();
137 }
138 }
139 };}
140
141macro_rules! add_assign_1d_range_vec_b {
142 ($source:expr, $ix:expr, $sink:expr) => {
143 unsafe {
144 for i in 0..($ix).len() {
145 if $ix[i] == true {
146 ($sink)[i] += ($source)[i].clone();
147 }
148 }
149 }
150 };}
151
152#[cfg(feature = "matrix")]
153impl_add_assign_range_fxn_s!(AddAssign1DRS,add_assign_1d_range,usize);
154#[cfg(feature = "matrix")]
155impl_add_assign_range_fxn_s!(AddAssign1DRB,add_assign_1d_range_b,bool);
156#[cfg(feature = "matrix")]
157impl_add_assign_range_fxn_v!(AddAssign1DRV,add_assign_1d_range_vec,usize);
158#[cfg(feature = "matrix")]
159impl_add_assign_range_fxn_v!(AddAssign1DRVB,add_assign_1d_range_vec_b,bool);
160
161op_assign_range_fxn!(add_assign_range_fxn, AddAssign1DR);
162
163pub struct AddAssignRange {}
164impl NativeFunctionCompiler for AddAssignRange {
165 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
166 if arguments.len() <= 1 {
167 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() },None).with_compiler_loc());
168 }
169 let sink: Value = arguments[0].clone();
170 let source: Value = arguments[1].clone();
171 let ixes = arguments.clone().split_off(2);
172 match add_assign_range_fxn(sink.clone(),source.clone(),ixes.clone()) {
173 Ok(fxn) => Ok(fxn),
174 Err(x) => {
175 match (&sink,&ixes,&source) {
176 (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { add_assign_range_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
177 (sink,ixes,Value::MutableReference(source)) => { add_assign_range_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
178 (Value::MutableReference(sink),ixes,source) => { add_assign_range_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
179 (sink, ixes, source) => Err(MechError2::new(
180 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "math/add-assign/range".to_string() },
181 None
182 ).with_compiler_loc()
183 ),
184 }
185 }
186 }
187 }
188}
189
190register_descriptor! {
191 FunctionCompilerDescriptor {
192 name: "math/add-assign/range",
193 ptr: &AddAssignRange{},
194 }
195}
196
197macro_rules! add_assign_2d_vector_all {
200 ($source:expr, $ix:expr, $sink:expr) => {
201 for cix in 0..($sink).ncols() {
202 for rix in $ix.iter() {
203 ($sink).column_mut(cix)[rix - 1] += ($source).clone();
204 }
205 }
206 };}
207
208macro_rules! add_assign_2d_vector_all_b {
209 ($source:expr, $ix:expr, $sink:expr) => {
210 for cix in 0..($sink).ncols() {
211 for rix in 0..$ix.len() {
212 if $ix[rix] == true {
213 ($sink).column_mut(cix)[rix] += ($source).clone();
214 }
215 }
216 }
217 };}
218
219macro_rules! add_assign_2d_vector_all_mat {
220 ($source:expr, $ix:expr, $sink:expr) => {
221 {
222 let nsrc = $source.nrows();
223 for (i, &rix) in $ix.iter().enumerate() {
224 let row_index = rix - 1;
225 let mut sink_row = $sink.row_mut(row_index);
226 let src_row = $source.row(i % nsrc); for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
228 *dst += *src;
229 }
230 }
231 }
232 };}
233
234macro_rules! add_assign_2d_vector_all_mat_b {
235 ($source:expr, $ix:expr, $sink:expr) => {
236 {
237 let mut src_i = 0;
238 for (i, rix) in (&$ix).iter().enumerate() {
239 if *rix == true {
240 let mut sink_row = ($sink).row_mut(i);
241 let src_row = ($source).row(src_i);
242 for (dst, src) in sink_row.iter_mut().zip(src_row.iter()) {
243 *dst += *src;
244 }
245 src_i += 1;
246 }
247 }
248 }
249 };}
250
251#[cfg(feature = "matrix")]
252impl_add_assign_range_fxn_s!(AddAssign2DRAS, add_assign_2d_vector_all,usize);
253#[cfg(feature = "matrix")]
254impl_add_assign_range_fxn_s!(AddAssign2DRASB,add_assign_2d_vector_all_b,bool);
255#[cfg(feature = "matrix")]
256impl_add_assign_range_fxn_v!(AddAssign2DRAV, add_assign_2d_vector_all_mat,usize);
257#[cfg(feature = "matrix")]
258impl_add_assign_range_fxn_v!(AddAssign2DRAVB,add_assign_2d_vector_all_mat_b,bool);
259
260op_assign_range_all_fxn!(add_assign_range_all_fxn, AddAssign2DRA);
261
262pub struct AddAssignRangeAll {}
263impl NativeFunctionCompiler for AddAssignRangeAll {
264 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
265 if arguments.len() <= 1 {
266 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() },None).with_compiler_loc());
267 }
268 let sink: Value = arguments[0].clone();
269 let source: Value = arguments[1].clone();
270 let ixes = arguments.clone().split_off(2);
271 match add_assign_range_all_fxn(sink.clone(),source.clone(),ixes.clone()) {
272 Ok(fxn) => Ok(fxn),
273 Err(_) => {
274 match (sink,ixes,source) {
275 (Value::MutableReference(sink),ixes,Value::MutableReference(source)) => { add_assign_range_all_fxn(sink.borrow().clone(),source.borrow().clone(),ixes.clone()) },
276 (sink,ixes,Value::MutableReference(source)) => { add_assign_range_all_fxn(sink.clone(),source.borrow().clone(),ixes.clone()) },
277 (Value::MutableReference(sink),ixes,source) => { add_assign_range_all_fxn(sink.borrow().clone(),source.clone(),ixes.clone()) },
278 (sink, ixes, source) => Err(MechError2::new(
279 UnhandledFunctionArgumentIxes { arg: (sink.kind(), ixes.iter().map(|x| x.kind()).collect(), source.kind()), fxn_name: "math/add-assign/range-all".to_string() },
280 None
281 ).with_compiler_loc()
282 ),
283 }
284 }
285 }
286 }
287}
288
289register_descriptor! {
290 FunctionCompilerDescriptor {
291 name: "math/add-assign/range-all",
292 ptr: &AddAssignRangeAll{},
293 }
294}