smc_doubleN.c (5574B)
1 /* Copyright (C) 2015-2018, 2021-2023 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "smc.h" 17 #include <rsys/dynamic_array_double.h> 18 #include <math.h> 19 20 /******************************************************************************* 21 * smc_doubleN functions 22 ******************************************************************************/ 23 static void 24 smc_doubleN_destroy(struct mem_allocator* allocator, void* data) 25 { 26 struct darray_double* dblN = data; 27 ASSERT(data); 28 darray_double_release(dblN); 29 MEM_RM(allocator, dblN); 30 } 31 32 static void* 33 smc_doubleN_create(struct mem_allocator* allocator, void* context) 34 { 35 struct smc_doubleN_context* ctx = context; 36 struct darray_double* dblN = NULL; 37 res_T res = RES_OK; 38 ASSERT(allocator); 39 40 if(!ctx || !ctx->count) goto error; 41 42 dblN = MEM_ALLOC(allocator, sizeof(struct darray_double)); 43 if(!dblN) goto error; 44 45 darray_double_init(allocator, dblN); 46 res = darray_double_resize(dblN, ctx->count); 47 if(res != RES_OK) goto error; 48 49 exit: 50 return dblN; 51 error: 52 if(dblN) { 53 smc_doubleN_destroy(allocator, dblN); 54 dblN = NULL; 55 } 56 goto exit; 57 } 58 59 static void 60 smc_doubleN_set(void* result, const void* value) 61 { 62 struct darray_double* dst = result; 63 const struct darray_double* src = value; 64 size_t i, n; 65 ASSERT(dst && src); 66 67 n = darray_double_size_get(dst); 68 if(n != darray_double_size_get(src)) { 69 FATAL("The vectors must have the same dimension.\n"); 70 } 71 FOR_EACH(i, 0, n) { 72 darray_double_data_get(dst)[i] = darray_double_cdata_get(src)[i]; 73 } 74 } 75 76 static void 77 smc_doubleN_zero(void* result) 78 { 79 struct darray_double* dblN = result; 80 ASSERT(result); 81 memset(darray_double_data_get(dblN), 0, 82 darray_double_size_get(dblN)*sizeof(double)); 83 } 84 85 static void 86 smc_doubleN_add(void* result, const void* op0, const void* op1) 87 { 88 struct darray_double* dst = result; 89 const struct darray_double* a = op0; 90 const struct darray_double* b = op1; 91 size_t i, n; 92 ASSERT(result && op0 && op1); 93 94 n = darray_double_size_get(dst); 95 if(n != darray_double_size_get(a) || n != darray_double_size_get(b)) { 96 FATAL("The vectors must have the same dimension.\n"); 97 } 98 FOR_EACH(i, 0, n) { 99 darray_double_data_get(dst)[i] = 100 darray_double_cdata_get(a)[i] + darray_double_cdata_get(b)[i]; 101 } 102 } 103 104 static void 105 smc_doubleN_sub(void* result, const void* op0, const void* op1) 106 { 107 struct darray_double* dst = result; 108 const struct darray_double* a = op0; 109 const struct darray_double* b = op1; 110 size_t i, n; 111 ASSERT(result && op0 && op1); 112 113 n = darray_double_size_get(dst); 114 if(n != darray_double_size_get(a) || n != darray_double_size_get(b)) { 115 FATAL("The vectors must have the same dimension.\n"); 116 } 117 FOR_EACH(i, 0, n) { 118 darray_double_data_get(dst)[i] = 119 darray_double_cdata_get(a)[i] - darray_double_cdata_get(b)[i]; 120 } 121 } 122 123 static void 124 smc_doubleN_mul(void* result, const void* op0, const void* op1) 125 { 126 struct darray_double* dst = result; 127 const struct darray_double* a = op0; 128 const struct darray_double* b = op1; 129 size_t i, n; 130 ASSERT(result && op0 && op1); 131 132 n = darray_double_size_get(dst); 133 if(n != darray_double_size_get(a) || n != darray_double_size_get(b)) { 134 FATAL("The vectors must have the same dimension.\n"); 135 } 136 FOR_EACH(i, 0, n) { 137 darray_double_data_get(dst)[i] = 138 darray_double_cdata_get(a)[i] * darray_double_cdata_get(b)[i]; 139 } 140 } 141 142 static void 143 smc_doubleN_divi(void* result, const void* op0, const size_t op1) 144 { 145 struct darray_double* dst = result; 146 const struct darray_double* a = op0; 147 size_t i, n; 148 ASSERT(result && op0 && op1); 149 150 n = darray_double_size_get(dst); 151 if(n != darray_double_size_get(a)) { 152 FATAL("The vectors must have the same dimension.\n"); 153 } 154 FOR_EACH(i, 0, n) { 155 darray_double_data_get(dst)[i] = darray_double_cdata_get(a)[i]/(double)op1; 156 } 157 } 158 159 static void 160 smc_doubleN_sqrt(void* result, const void* value) 161 { 162 struct darray_double* dst = result; 163 const struct darray_double* src = value; 164 size_t i, n; 165 ASSERT(result && value); 166 167 n = darray_double_size_get(dst); 168 if(n != darray_double_size_get(src)) { 169 FATAL("The vectors must have the same dimension.\n"); 170 } 171 FOR_EACH(i, 0, n) { 172 darray_double_data_get(dst)[i] = sqrt(darray_double_cdata_get(src)[i]); 173 } 174 } 175 176 /******************************************************************************* 177 * Exported helper function 178 ******************************************************************************/ 179 double* 180 SMC_DOUBLEN(void* val) 181 { 182 ASSERT(val); 183 return darray_double_data_get(val); 184 } 185 186 /******************************************************************************* 187 * Exported type 188 ******************************************************************************/ 189 const struct smc_type smc_doubleN = { 190 smc_doubleN_create, 191 smc_doubleN_destroy, 192 smc_doubleN_set, 193 smc_doubleN_zero, 194 smc_doubleN_add, 195 smc_doubleN_sub, 196 smc_doubleN_mul, 197 smc_doubleN_divi, 198 smc_doubleN_sqrt 199 }; 200