static int vector_double_op(zend_uchar opcode, zval *result, zval *vec, double value) /* {{{ */ { switch(opcode) { case ZEND_MUL: return vector_mul(result, vec, value); case ZEND_DIV: return vector_div(result, vec, value); } zend_throw_exception(NULL, "Unsupported vector operation", 0); return FAILURE; }
static t_color3 getfinalcolor(t_object *light, t_intersect inter) { t_color3 color; unsigned int i; color = color_new(0., 0., 0.); if (inter.obj) { i = 0; while(light[i].type != DEFAULT) { color = vector_sum(iter_light(inter, (t_spotlight *)&light[i]), color); ++i; } return (vector_div(color, i)); } return (color_new(17, 25, 37)); }
static t_color3 getfinalcolor(t_object *arr, t_intersect inter, t_env env) { t_color3 color; t_color3 color_tmp; float dist[2]; t_ray newray; float shade; t_vector3 l; int i; int k; int a; color_tmp = color_new(0, 0, 0); a = 0; if (inter.obj) { i = -1; while(arr[i].type != DEFAULT) { shade = 1.0; if (arr[i].light == TRUE) { l = vector_substract(arr[i].pos, inter.pos); dist[0] = vector_magnitude(l); newray.pos = vector_substract(inter.pos, vector_mul(inter.v_normal, 1e-4f)); newray.dir = vector_unit(l); k = -1; while (++k < 16 && arr[k].type != DEFAULT) if (env.fctinter[arr[k].type](newray, arr + k, &dist[1])) { if (arr[k].light != TRUE && dist[1] <= dist[0]) shade -= 0.3; } color_tmp = vector_sum(color_tmp, iter_light(inter, &arr[i], shade)); ++a; } ++i; } return (vector_div(color_tmp, a)); } return (color_new(17, 25, 37)); }
static PyObject *nipals2(PyObject *self, PyObject *args) /* fills the Scores and Loadings matrices and returns explained_var array */ { /* Estimation of PC components with the iterative NIPALS method: E[0] = mean_center(X) (the E-matrix for the zero-th PC) t = E(:, 0) (a column in X (mean centered) is set as starting t vector) for i=1 to (PCs): 1 p=(E[i-1]'t) / (t't) Project X onto t to find the corresponding loading p 2 p = p * (p'p)^-0.5 Normalise loading vector p to length 1 3 t = (E[i-1]p) / (p'p) Project X onto p to find corresponding score vector t 4 Check for convergence, if difference between eigenval_new and eigenval_old is larger than threshold*eigenval_new return to step 1 5 E[i] = E[i-1] - tp' Remove the estimated PC component from E[i-1] */ PyArrayObject *Scores, *Loadings, *E, *Error_matrices; double threshold, eigenval_t, eigenval_p, eigenval_new; double eigenval_old = 0.0; double temp; int i, j, k, PCs, cols, rows, cols_t, rows_t; int convergence, ready_for_compare; /* Get arguments: */ if (!PyArg_ParseTuple(args, "O!O!O!O!id:nipals2", &PyArray_Type, &Scores, &PyArray_Type, &Loadings, &PyArray_Type, &E, &PyArray_Type, &Error_matrices, &PCs, &threshold)) { return NULL; } /* safety checks */ if (NULL == Scores) return NULL; if (NULL == Loadings) return NULL; if (NULL == E) return NULL; if (Scores->nd != 2) { PyErr_Format(PyExc_ValueError, "Scores array has wrong dimension (%d)", Scores->nd); return NULL; } if (Loadings->nd != 2) { PyErr_Format(PyExc_ValueError, "Loadings array has wrong dimension (%d)", Loadings->nd); return NULL; } if (E->nd != 2) { PyErr_Format(PyExc_ValueError, "E array has wrong dimension (%d)", E->nd); return NULL; } if (Error_matrices->nd != 3) { PyErr_Format(PyExc_ValueError, "Error_matrices array has wrong dimension (%d)", Error_matrices->nd); return NULL; } //TYPECHECK(Scores, PyArray_DOUBLE); //TYPECHECK(Loadings, PyArray_DOUBLE); //TYPECHECK(E, PyArray_DOUBLE); rows = E->dimensions[0]; cols = E->dimensions[1]; /* Set 2d array pointer e */ double *data_ptr; data_ptr = (double *) E->data; /* is a PyArrayObject* pointer */ double **e; e = (double **) malloc((rows)*sizeof(double*)); for (i = 0; i < rows; i++) { e[i] = &(data_ptr[i*cols]); /* point row no. i in E->data */ } /* Set 3d array pointer e_matrices double *data_ptr2; data_ptr2 = (double *) Error_matrices->data; // is a PyArrayObject* pointer double ***e_matrices; e_matrices = (double ***) malloc((rows)*sizeof(double*)); for (i = 0; i < PCs; i++) { for (j = 0; j < rows; j ++) { e_matrices[i][j] = &(data_ptr2[i*cols*rows]); } // point array (i,j) in Error_matrices->data }*/ /* Set t vector */ double t[rows]; double p[cols]; //for(i = 0; i < rows; i++) //{ t[i] = e[i][0]; } get_column(t, e, cols, rows); /* Transposed E[0] */ cols_t = rows; rows_t = cols; double **e_transposed; e_transposed = (double **) malloc((rows_t)*sizeof(double*)); for (i = 0; i < rows_t; i++) { e_transposed[i] = (double *) malloc((cols_t)*sizeof(double)); } /* Do iterations (0, PCs) */ for(i = 0; i < PCs; i++) { convergence = 0; ready_for_compare = 0; transpose(e, e_transposed, cols, rows); while(convergence == 0) { // 1 p=(E[i-1]'t) / (t't) Project X onto t to find the corresponding loading p matrix_vector_prod(e_transposed, cols_t, rows_t, t, p); eigenval_t = vector_eigenval(t, rows); vector_div(p, cols, eigenval_t); // 2 p = p * (p'p)^-0.5 Normalise loading vector p to length 1 eigenval_p = vector_eigenval(p, cols); temp = pow(eigenval_p, (-0.5)); vector_mul(p, cols, temp); // 3 t = (E[i-1]p) / (p'p) Project X onto p to find corresponding score vector t matrix_vector_prod(e, cols, rows, p, t); eigenval_p = vector_eigenval(p, cols); vector_div(t, rows, eigenval_p); // 4 Check for convergence eigenval_new = vector_eigenval(t, rows); if(ready_for_compare == 0) { ready_for_compare = 1; } else { if((eigenval_new - eigenval_old) < threshold*eigenval_new) { convergence = 1; } } eigenval_old = eigenval_new; } // 5 E[i] = E[i-1] - tp' Remove the estimated PC component from E[i-1] and sets result to E[i] remove_tp(e, cols, rows, t, p); /* Add current Scores and Loadings to collection */ for(j = 0; j < rows; j++){ IND2(Scores, j, i) = t[j]; } for(j = 0; j < cols; j++){ IND2(Loadings, i, j) = p[j]; } /* Add current E to Error_matrices */ for(j = 0; j < rows; j++) { for(k = 0; k < cols; k++) { IND3(Error_matrices, i, j, k) = e[j][k]; } } } free(e); for (i = 0; i < rows_t; i++) { free(e_transposed[i]); } free(e_transposed); return PyInt_FromLong(1); }
inline Vector *vector_div_true(Vector *a, double d) { return vector_div(a,d,a); }
inline Vector *vector_normalize(Vector *a) { return vector_div(a, vector_length(a), NULL); }