static void dwt_step (const gsl_wavelet * w, double *a, size_t stride, size_t n, gsl_wavelet_direction dir, gsl_wavelet_workspace * work) { double ai, ai1; size_t i, ii; size_t jf; size_t k; size_t n1, ni, nh, nmod; for (i = 0; i < work->n; i++) { work->scratch[i] = 0.0; } nmod = w->nc * n; nmod -= w->offset; /* center support */ n1 = n - 1; nh = n >> 1; if (dir == gsl_wavelet_forward) { for (ii = 0, i = 0; i < n; i += 2, ii++) { double h = 0, g = 0; ni = i + nmod; for (k = 0; k < w->nc; k++) { jf = n1 & (ni + k); h += w->h1[k] * ELEMENT (a, stride, jf); g += w->g1[k] * ELEMENT (a, stride, jf); } work->scratch[ii] += h; work->scratch[ii + nh] += g; } } else { for (ii = 0, i = 0; i < n; i += 2, ii++) { ai = ELEMENT (a, stride, ii); ai1 = ELEMENT (a, stride, ii + nh); ni = i + nmod; for (k = 0; k < w->nc; k++) { jf = (n1 & (ni + k)); work->scratch[jf] += (w->h2[k] * ai + w->g2[k] * ai1); } } } for (i = 0; i < n; i++) { ELEMENT (a, stride, i) = work->scratch[i]; } }
void init_mat(void) { matrix_begin(); matrix_t* A = matrix_matrix(2, 2); ELEMENT(A, 0, 0) = 1.0; ELEMENT(A, 0, 0) = 3.0; ELEMENT(A, 0, 0) = 2.0; ELEMENT(A, 0, 0) = 4.0; sq_init_matrix(A); matrix_end(); }
// non autorelease function // maのia行目にaをかけた値と、mbのib行目にbをかけた値の和を、mdestのidestに代入 void matrix_row_linear_comb(float a, matrix_t* ma, int ia, float b, matrix_t* mb, int ib, matrix_t* mdest, int idest) { if (ma->cols != mb->cols) assert(0); int i; for (i=0;i<ma->cols;i++) ELEMENT(mdest, idest, i) = a * ELEMENT(ma, ia, i) + b * ELEMENT(mb, ib, i); }
// non autorelease function void matrix_copy_row(matrix_t* msrc, int isrc, matrix_t* mdest, int idest) { if (msrc->cols != mdest->cols) assert(0); int i; for (i = 0; i < msrc->cols;i++) ELEMENT(mdest, idest, i) = ELEMENT(msrc, isrc, i); }
static Element * mesh_find_large_element( const Mesh *mesh, gdouble max_element_area ) { GList *elements_iter; for ( elements_iter = mesh->elements; elements_iter != NULL; elements_iter = g_list_next( elements_iter ) ) { if ( element_area( ELEMENT( elements_iter->data ) ) > max_element_area ) return ELEMENT( elements_iter->data ); } return NULL; }
// autorelease function // 転置 matrix_t* matrix_transpose(matrix_t* a) { int r, c; matrix_t* t = matrix_alloc(a->cols, a->rows); for (r = 0; r < t->rows; r++) { for (c = 0; c < t->cols; c++) { MATRIX_ASSERT(t, r, c); MATRIX_ASSERT(a, c, r); ELEMENT(t, r, c) = ELEMENT(a, c, r); } } return matrix_autorelease(t); }
// a:n*1 b:n*n c:n*1として、a^T b cの二次形式を計算する。 value_t matrix_quadratic(matrix_t* a, matrix_t* b, matrix_t* c) { if (!(a->cols == 1 && c->cols == 1 && a->rows == b->cols && b->cols == b->rows && b->rows == c->rows)) { assert(0); } int i, j; value_t sum = 0.0; for (i = 0; i < b->cols; i++) for (j = 0; j < b->cols; j++) sum += ELEMENT(a, i, 0) * ELEMENT(c, j, 0) * ELEMENT(b, i, j); return sum; }
void matrix_fill_zero(matrix_t* mat) { int i, j; for (i = 0; i < mat->rows; i++) for (j = 0; j < mat->cols; j++) ELEMENT(mat, i, j) = 0.0; }
/*--------------------------------------------------------------------------- * Destroy element * * \param device * \param element *----------------------------------------------------------------------------*/ OWF_API_CALL WFCErrorCode WFC_Device_DestroyElement(WFC_DEVICE* device, WFCElement element) { WFCint i; WFCErrorCode result = WFC_ERROR_BAD_HANDLE; ENTER(WFC_Device_DestroyElement); FAIL_IF(NULL == device, WFC_ERROR_BAD_HANDLE); DPRINT(("destroying element %d", element)); for (i = 0; i < device->elements.length; i++) { WFC_ELEMENT* object; object = ELEMENT(OWF_Array_GetItemAt(&device->elements, i)); DPRINT((" element %d = %d", i, object->handle)); if (object->handle == element) { WFC_Context_RemoveElement(CONTEXT(object->context), element); WFC_Context_DecreaseClientElementCount(object->context); OWF_Array_RemoveItemAt(&device->elements, i); WFC_Element_Destroy(object); result = WFC_ERROR_NONE; break; } } LEAVE(WFC_Device_DestroyElement); return result; }
/*--------------------------------------------------------------------------- * Called from context's destructor to clean up any elements that * weren't added to any scene at all i.e. they only reside in the * device's element list. These elements must not stay alive after * the context has been deleted. *----------------------------------------------------------------------------*/ OWF_API_CALL void WFC_Device_DestroyContextElements(WFC_DEVICE* device, WFC_CONTEXT* context) { WFCint i; DPRINT(("WFC_Device_DestroyContextElements(device=%d, context=%d", device ? device->handle : 0, context ? context->handle : 0)); if (!device || !context) { return; } for (i = device->elements.length; i > 0; i--) { WFC_ELEMENT* element; element = ELEMENT(OWF_Array_GetItemAt(&device->elements, i-1)); if (element->context == context) { DPRINT((" Destroying element %d (%p)", element->handle, element)); /* Improvement idea: This code is partially same as in * WFC_Device_RemoveElement. Maybe the common part should * be isolated into some DoRemoveElement function which then * would be called from here and RemoveElement. */ WFC_Context_RemoveElement(CONTEXT(element->context), element->handle); OWF_Array_RemoveItemAt(&device->elements, i-1); WFC_Element_Destroy(element); } } }
// autorelease function matrix_t* matrix_unit(int dim) { if (dim < 1) { assert(0); } matrix_t* r = matrix_alloc(dim, dim); int i, j; for (i = 0; i < dim; i++) for (j = 0; j < dim; j++) ELEMENT(r, i, j) = 0.0; for (i = 0; i < dim; i++) ELEMENT(r, i, i) = 1; return matrix_autorelease(r); }
static void *requests_status_init(void) { struct st_requests_status_ctx_t *rsc = h2o_mem_alloc(sizeof(*rsc)); char errbuf[256]; #define ELEMENT(key, expr) "\"" key "\": \"" expr "\"" #define X_ELEMENT(id) ELEMENT(id, "%{" id "}x") #define SEPARATOR ", " const char *fmt = ",\n {" /* combined_log */ ELEMENT("host", "%h") SEPARATOR ELEMENT("user", "%u") SEPARATOR ELEMENT("at", "%{%Y%m%dT%H%M%S}t.%{usec_frac}t%{%z}t") SEPARATOR ELEMENT("method", "%m") SEPARATOR ELEMENT("path", "%U") SEPARATOR ELEMENT("query", "%q") SEPARATOR ELEMENT("protocol", "%H") SEPARATOR ELEMENT("referer", "%{Referer}i") SEPARATOR ELEMENT("user-agent", "%{User-agent}i") SEPARATOR /* time */ X_ELEMENT("connect-time") SEPARATOR X_ELEMENT("request-header-time") SEPARATOR X_ELEMENT("request-body-time") SEPARATOR X_ELEMENT("request-total-time") SEPARATOR X_ELEMENT("process-time") SEPARATOR X_ELEMENT("response-time") SEPARATOR /* connection */ X_ELEMENT("connection-id") SEPARATOR X_ELEMENT("ssl.protocol-version") SEPARATOR X_ELEMENT("ssl.session-reused") SEPARATOR X_ELEMENT("ssl.cipher") SEPARATOR X_ELEMENT("ssl.cipher-bits") SEPARATOR /* http1 */ X_ELEMENT("http1.request-index") SEPARATOR /* http2 */ X_ELEMENT("http2.stream-id") SEPARATOR X_ELEMENT("http2.priority.received.exclusive") SEPARATOR X_ELEMENT("http2.priority.received.parent") SEPARATOR X_ELEMENT("http2.priority.received.weight") SEPARATOR X_ELEMENT("http2.priority.actual.parent") SEPARATOR X_ELEMENT("http2.priority.actual.weight") SEPARATOR /* misc */ ELEMENT("authority", "%V") /* end */ "}"; #undef ELEMENT #undef X_ELEMENT #undef SEPARATOR /* compile logconf */ if ((rsc->logconf = h2o_logconf_compile(fmt, H2O_LOGCONF_ESCAPE_JSON, errbuf)) == NULL) /* log format compilation error is an internal logic flaw, therefore we need not send the details to the client */ fprintf(stderr, "[lib/handler/status/requests.c] failed to compile log format: %s", errbuf); #ifndef _MSC_VER rsc->req_data = (h2o_iovec_t){NULL}; #else rsc->req_data = (h2o_iovec_t) { 0 }; #endif #ifndef _MSC_VER pthread_mutex_init(&rsc->mutex, NULL); #else uv_mutex_init(&rsc->mutex); #endif return rsc; }
/* Called for close tags </foo> */ void xmlcar_end (GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { xmlcar_t *xc = (xmlcar_t *)user_data; if (ELEMENT("car") && xc->level == 1) xc->level = 0; else if (ELEMENT("engine") && xc->level == 2) xc->level = 1; else if (ELEMENT("gearbox") && xc->level == 3) xc->level = 1; /*else if (ELEMENT("torque") || ELEMENT("GEAR") || ELEMENT("differential") || ELEMENT()) else g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "bad file structure (bad closing tag %s)", element_name);*/ }
int matrix_compare_with_precision(matrix_t* a, matrix_t* b, value_t precision) { if (a->rows != b->rows) return 0; if (a->cols != b->cols) return 0; int i, j; int flag = 1; for (i = 0; i < a->rows; i++) { for (j = 0; j < a->cols; j++) { if (ABS(ELEMENT(a, i, j) - ELEMENT(b, i, j)) > precision) { flag = 0; break; } } } return flag; }
static Element * mesh_find_skinny_element( const Mesh *mesh, gdouble min_angle ) { GList *elements_iter; for ( elements_iter = mesh->elements; elements_iter != NULL; elements_iter = g_list_next( elements_iter ) ) { gdouble el_min_angle = element_minimum_angle( ELEMENT( elements_iter->data ) ); if ( el_min_angle < min_angle ) return ELEMENT( elements_iter->data ); } return NULL; /* using the following code we return the most skinny element, but we have * to sort the elements, which is something that I do not want to do at * this point. This whole thing of deciding which elements to refine has to * be implemented in a better way anyway */ /* mesh->elements = g_list_sort( mesh->elements, compare_element_quality ); if ( element_minimum_angle( ELEMENT( mesh->elements->data ) ) < min_angle ) return ELEMENT( mesh->elements->data ); else return NULL; */ }
// autorelease function matrix_t* matrix_product(matrix_t* a, matrix_t* b) { int r, c, j; if (a->cols != b->rows) return NULL; matrix_t* product = matrix_alloc(a->rows, b->cols); for (r = 0; r < product->rows; r++) { for (c = 0; c < product->cols; c++) { value_t sum = 0; for (j = 0; j < a->cols; j++) { MATRIX_ASSERT(a, r, j); MATRIX_ASSERT(a, j, c); sum += ELEMENT(a, r, j) * ELEMENT(b, j, c); } MATRIX_ASSERT(product, r, c); ELEMENT(product, r, c) = sum; } } return matrix_autorelease(product); }
void heap_bubble_up(heap_t* heap, int index) { int i = index; void* e = ELEMENT(heap, i); void* p = ELEMENT(heap, PARENT_INDEX(i)); void* tmp = malloc(heap->element_size); if(tmp == NULL) { printf("Cannot allocate memory for temporary element.\n"); return; } while(e != heap->top && heap->element_cmp(e, p) == 1) { memcpy(tmp, p, heap->element_size); memcpy(p, e, heap->element_size); memcpy(e, tmp, heap->element_size); i = PARENT_INDEX(i); e = ELEMENT(heap, i); p = ELEMENT(heap, PARENT_INDEX(i)); } free(tmp); }
void heap_remove_top(heap_t* heap) { if(heap->n_elements == 1) { free(heap->top); heap->top = NULL; heap->n_elements--; } else { memcpy(heap->top, ELEMENT(heap, heap->n_elements - 1), heap->element_size); heap->n_elements--; heap->top = realloc(heap->top, heap->element_size * heap->n_elements); heap_bubble_down(heap, 0); } }
/*--------------------------------------------------------------------------- * Destroy all elements from device * * \param device Device *----------------------------------------------------------------------------*/ OWF_API_CALL void WFC_Device_DestroyElements(WFC_DEVICE* device) { WFCint i; ENTER(WFC_Device_DestroyElements); OWF_ASSERT(device); for (i = 0; i < device->elements.length; i++) { WFC_ELEMENT* etemp; etemp = ELEMENT(OWF_Array_GetItemAt(&device->elements, i)); WFC_Element_Destroy(etemp); } OWF_Array_Destroy(&device->elements); LEAVE(WFC_Device_DestroyElements); }
int main(int argc, char** argv) { printf("--------verify--------\n"); verify_matrix(); printf("----------------------\n"); // autorelease関数をbeginとendにはさまないで使うのはNG // 全てのallocされた関数は // (1) free // (2) release // (3) begin-endの中でautorelease // のいずれかを行う必要がある。 // 擬似逆行列演算がこれくらい簡単に記述できる。 /* 3*2行列aを確保、成分ごとの代入 */ matrix_t* a = matrix_alloc(3, 2); ELEMENT(a, 0, 0) = 1; ELEMENT(a, 0, 1) = 4; ELEMENT(a, 1, 0) = 2; ELEMENT(a, 1, 1) = 5; ELEMENT(a, 2, 0) = 3; ELEMENT(a, 2, 1) = 6; /* 擬似逆行列の演算 */ // auto releaseモードに入る matrix_begin(); // 擬似逆行列を求める。一行だけ! matrix_t* inva = matrix_product(matrix_inverse(matrix_product(matrix_transpose(a), a)), matrix_transpose(a)); // 擬似逆行列の表示 (invaはmatrix_endで解放されるので、begin-end内で。) matrix_print(inva); // release poolを開放する matrix_end(); /* ちなみに擬似逆行列を求める関数は内部に組んだので、それを使うこともできる。 */ // auto releaseモードに入る matrix_begin(); // 擬似逆行列を求める関数を呼ぶ。 matrix_t* inva_simple = matrix_pseudo_inverse(a); // 擬似逆行列の表示 (invaはmatrix_endで解放されるので、begin-end内で。) matrix_print(inva_simple); // release poolを開放する matrix_end(); // これはautorelease対象でないので、しっかり自分でfree。 // リテインカウントを実装してあるので、理解できればreleaseの方が高性能。 //matrix_free(a); matrix_release(a); return 0; }
/*--------------------------------------------------------------------------- * Find element by handle * * \param device Device * \param el Element handle * * \return Element object *----------------------------------------------------------------------------*/ OWF_API_CALL WFC_ELEMENT* WFC_Device_FindElement(WFC_DEVICE* device, WFCElement el) { WFC_ELEMENT* result = WFC_INVALID_HANDLE; WFCint i; FAIL_IF(NULL == device, NULL); for (i = 0; i < device->elements.length; i++) { WFC_ELEMENT* element; element = ELEMENT(OWF_Array_GetItemAt(&device->elements, i)); if (element->handle == el) { result = element; break; } } return result; }
/* Called for open tags <foo bar="baz"> */ void xmlcar_start (GMarkupParseContext *context, const gchar *element_name, const gchar **attribute_names, const gchar **attribute_values, gpointer user_data, GError **error) { xmlcar_t *xc = (xmlcar_t *)user_data; car_t *car = xc->car; if (ELEMENT("car") && xc->level == 0) xc->level = 1; else if (ELEMENT("engine") && xc->level == 1) { const char **at, **av; gboolean minok=FALSE, maxok=FALSE; for (at=attribute_names, av=attribute_values; *at; at++, av++) if (strcmp(*at, "minrpm") == 0) { xc->car->minrpm = atoi(*av); xc->nextrpm = xc->car->minrpm; minok = TRUE; } else if (strcmp(*at, "maxrpm") == 0) { xc->car->maxrpm = atoi(*av); maxok = TRUE; } if (!minok || !maxok || car->minrpm < 0 || car->minrpm>=car->maxrpm || car->maxrpm >= MAXRPM) g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "bad file structure (<car>: minrpm / maxrpm)"); car->parts |= CAR_PART_ENGINE; xc->level = 2; } else if (ELEMENT("torque") && xc->level == 2) car->torque[xc->nextrpm++] = ATTRD("value"); else if (ELEMENT("gearbox") && xc->level == 1) { xc->car->gears = 0; car->parts |= CAR_PART_GEARBOX; xc->level = 3; } else if (ELEMENT("gear") && xc->level == 3) { if (xc->car->gears == MAXGEARS) { g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "bad file structure (max gears count is %d)", MAXGEARS); return; } car->gear[car->gears++] = ATTRD("ratio"); } else if (ELEMENT("differential") && xc->level == 1) { car->differential = ATTRD("ratio"); car->parts |= CAR_PART_DIFF; } else if (ELEMENT("tire") && xc->level == 1) { car->tire_width = ATTRD("width"); car->tire_ratio = ATTRD("ratio"); car->tire_rim = ATTRD("rim"); car->parts |= CAR_PART_TIRE; } else if (ELEMENT("weight") && xc->level == 1) { car->weight = ATTRD("value"); car->parts |= CAR_PART_WEIGHT; } else g_set_error(error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "bad file structure (unsupported tag %s)", element_name); }
void heap_bubble_down(heap_t* heap, int index) { int i = index; int done = 0; int ri; int li; void* e; void* r; void* l; void* tmp = malloc(heap->element_size); if(tmp == NULL) { printf("Cannot allocate memory for temporary element.\n"); return; } while(!done && i < heap->n_elements) { li = LEFT_INDEX(i); ri = RIGHT_INDEX(i); e = ELEMENT(heap, i); l = ELEMENT(heap, li); r = ELEMENT(heap, ri); if(ri < heap->n_elements && li < heap->n_elements) { /* If the right child is the larger of the two and larger than * the parent, then swap parent and right child. */ if(heap->element_cmp(r, l) == 1 && heap->element_cmp(r, e) == 1) { memcpy(tmp, r, heap->element_size); memcpy(r, e, heap->element_size); memcpy(e, tmp, heap->element_size); i = ri; } else if(heap->element_cmp(l, e) == 1) { memcpy(tmp, l, heap->element_size); memcpy(l, e, heap->element_size); memcpy(e, tmp, heap->element_size); i = li; } else done = 1; } else if(ri < heap->n_elements && heap->element_cmp(r, e) == 1) { memcpy(tmp, r, heap->element_size); memcpy(r, e, heap->element_size); memcpy(e, tmp, heap->element_size); i = ri; } else if(li < heap->n_elements && heap->element_cmp(l, e) == 1) { memcpy(tmp, l, heap->element_size); memcpy(l, e, heap->element_size); memcpy(e, tmp, heap->element_size); i = li; } else done = 1; } free(tmp); }
// autorelease function matrix_t* matrix_inverse(matrix_t* m) { if (m->rows != m->cols) { assert(0); // not a square matrix } int i, j; int maxi; int nrc; nrc = m->rows; matrix_t* minv = matrix_alloc(nrc, nrc); matrix_t* vtmp = matrix_alloc(1, nrc); float tmp; matrix_begin(); matrix_t* mtmp = matrix_copy(m); for (i = 0; i < nrc * nrc; i++) { if (i / nrc == i % nrc) ELEMENT(minv,i/nrc,i%nrc) = 1.0f; else ELEMENT(minv,i/nrc,i%nrc) = 0.0f; } if (mtmp == NULL || minv == NULL) return NULL; for (i=0; i<nrc; i++) { maxi = i; for (j=i+1; j<nrc; j++) { if(ABS(ELEMENT(mtmp,maxi,i)) < ABS(ELEMENT(mtmp,j,i))) maxi = j; } if (ELEMENT(mtmp,maxi,i) == 0.0f) { printf("input matrix is invalid!\n"); break; } // 行入れ替え matrix_copy_row(mtmp, i, vtmp, 0); matrix_copy_row(mtmp, maxi, mtmp, i); matrix_copy_row(vtmp, 0, mtmp, maxi); // 行入れ替え matrix_copy_row(minv, i, vtmp, 0); matrix_copy_row(minv, maxi, minv, i); matrix_copy_row(vtmp, 0, minv, maxi); tmp = ELEMENT(mtmp,i,i); for (j=0; j<nrc; j++) { // j:列番号 ELEMENT(mtmp, i, j) = ELEMENT(mtmp, i, j)/tmp; ELEMENT(minv, i, j) = ELEMENT(minv, i, j)/tmp; } for (j=0; j<nrc; j++) { // j:行番号 if (i!=j) { tmp = ELEMENT(mtmp,j,i); matrix_row_linear_comb(-tmp, mtmp, i, 1.0f, mtmp, j, mtmp, j); matrix_row_linear_comb(-tmp, minv, i, 1.0f, minv, j, minv, j); } } } matrix_end(); matrix_free(vtmp); return matrix_autorelease(minv); }
/* *************************************************************************** ** Searches for a long value within an array. ** ** The array can either be an array of longs, or else an array of something ** bigger than a long which has one of its elements equal to the value that ** we seek. ** ** Returns three values - the exact value (if it exists), the lower bound ** and the upper bound. ** ** The lower bound is defined as the index of the last value which is ** strictly less than the desired value. ** ** The upper bound is defined as the index of the first value which is ** strictly greater than the desired value. ** ** The exact value is the index of a value which is equal to the desired ** value. ** ** In the case that such an index cannot be found, then the value of -1 ** is returned for exact and loBound, and arraySize for hiBound. ** ** The idea behind these return values is that hiBound-loBound-1 should ** give the number of exact matches in all cases, and that everything in ** the range [loBound+1, hiBound-1] inclusive should be an exact match. ** ** If the input array is not sorted in ascending order, then the output ** is undefined. No checks are performed on the order of xArray - this ** would in fact defeat the purpose of having a fast binary search if you ** are going to slow it down by doing a linear check of the inputs. *************************************************************************** */ int JpmcdsBinarySearchLong (long xDesired, /* (I) Value for which we seek */ long *xArray, /* (I) Array in which we seek - assumes sorted in ascending order.*/ size_t skip, /* (I) Size of elements in the array */ long arraySize, /* (I) Size of the array */ long *exact, /* (O) Index of a value which is equal to xDesired, -1 if not found */ long *loBound, /* (O) Index of last value strictly less than xDesired, -1 if no such value exists. */ long *hiBound) /* (O) Index of first value strictly greater than xDesired, -1 if no such value exists. */ { static char routine[] = "JpmcdsBinarySearchLong"; int status = FAILURE; int count; /* Used to check # search steps */ int lo; /* Index of low estimate */ int hi; /* Index of high estimate */ int mid = 0; /* Index of best estimate */ char *xp = (char *)xArray; /* Ptr to x array */ REQUIRE (arraySize > 0); REQUIRE (skip >= sizeof(long)); REQUIRE (exact != NULL); #undef ELEMENT #define ELEMENT(idx) *(long*)(xp + skip*(idx)) /* If we are not in the range then we are done */ if (xDesired < ELEMENT(0)) { *exact = -1; *loBound = -1; *hiBound = 0; return SUCCESS; } else if (xDesired > ELEMENT(arraySize-1)) { *exact = -1; *loBound = arraySize-1; *hiBound = arraySize; return SUCCESS; } /* arraySize of 1 we are done */ if (arraySize == 1) { // assert (xDesired == ELEMENT(0)); *exact = 0; *loBound = -1; *hiBound = arraySize; return SUCCESS; } lo = 0; hi = arraySize - 2; /* Do binary search to find pair of x's which surround the desired * X value. */ for (count = arraySize+1; count > 0; --count) { mid = (hi + lo) / 2; if (xDesired < ELEMENT(mid)) hi = mid - 1; else if (xDesired > ELEMENT(mid + 1)) lo = mid + 1; else break; /* Done */ } if (count == 0) { JpmcdsErrMsg("%s: x array not in increasing order.n", routine); return FAILURE; } /* Protect against a run of x values which are the same. * Set two surrounding indices to be lo and hi. * Note that there is no danger of running off the end * since the only way for x[lo] = x[hi] is for both * to be equal to xDesired. But from check at beginning, * we know X[N-1] <> xDesired. */ // assert (mid < arraySize); // assert (xDesired >= ELEMENT(mid)); // assert (xDesired <= ELEMENT(mid+1)); lo = mid; hi = mid+1; if (ELEMENT(lo) == xDesired) *exact = lo; else if (ELEMENT(hi) == xDesired) *exact = hi; else *exact = -1; if (loBound != NULL) { while (lo >= 0 && ELEMENT(lo) >= xDesired) --lo; if (lo >= 0) *loBound = lo; else *loBound = -1; } if (hiBound != NULL) { while (hi < arraySize && ELEMENT(hi) <= xDesired) ++hi; if (hi < arraySize) *hiBound = hi; else *hiBound = arraySize; } status = SUCCESS; done: if (status != SUCCESS) JpmcdsErrMsgFailure(routine); return status; }
// 行列式 value_t matrix_det(matrix_t* m) { if (m->rows != m->cols) { assert(0); // not a square matrix } if (m->rows == 2) { MATRIX_ASSERT(m, 1, 1); return ELEMENT(m, 0, 0) * ELEMENT(m, 1, 1) - ELEMENT(m, 0, 1) * ELEMENT(m, 1, 0); } if (m->rows == 3) { MATRIX_ASSERT(m, 2, 2); return \ ELEMENT(m, 0, 0) * ELEMENT(m, 1, 1) * ELEMENT(m, 2, 2) \ + ELEMENT(m, 0, 1) * ELEMENT(m, 1, 2) * ELEMENT(m, 2, 0) \ + ELEMENT(m, 0, 2) * ELEMENT(m, 1, 0) * ELEMENT(m, 2, 1) \ - ELEMENT(m, 0, 2) * ELEMENT(m, 1, 1) * ELEMENT(m, 2, 0) \ - ELEMENT(m, 0, 1) * ELEMENT(m, 1, 0) * ELEMENT(m, 2, 2) \ - ELEMENT(m, 0, 0) * ELEMENT(m, 1, 2) * ELEMENT(m, 2, 1); } assert(0); // other dimensions are not not supported }
(error)) PROXY_STUB (pa_stream_readable_size, size_t, (pa_stream *p), (p)) typedef struct { const char *name; void (**fn)(void); } SHARED_FUNC; #define ELEMENT(function) { #function , (void (**)(void)) & g_pfn_ ## function } static SHARED_FUNC SharedFuncs[] = { ELEMENT(pa_stream_connect_playback), ELEMENT(pa_stream_connect_record), ELEMENT(pa_stream_disconnect), ELEMENT(pa_stream_get_sample_spec), ELEMENT(pa_stream_set_latency_update_callback), ELEMENT(pa_stream_write), ELEMENT(pa_stream_unref), ELEMENT(pa_stream_get_state), ELEMENT(pa_stream_set_state_callback), ELEMENT(pa_stream_flush), ELEMENT(pa_stream_drain), ELEMENT(pa_stream_trigger), ELEMENT(pa_stream_new), ELEMENT(pa_stream_get_buffer_attr), ELEMENT(pa_stream_peek), ELEMENT(pa_stream_cork),
// autorelease function matrix_t* matrix_exterior(matrix_t* a) { if (a->rows != 3 || a->cols != 1) { assert(0); } matrix_t* r = matrix_alloc(3, 3); ELEMENT(r, 0, 0) = 0; ELEMENT(r, 0, 1) = -ELEMENT(a, 2, 0); ELEMENT(r, 0, 2) = ELEMENT(a, 1, 0); ELEMENT(r, 1, 0) = ELEMENT(a, 2, 0); ELEMENT(r, 1, 1) = 0; ELEMENT(r, 1, 2) = -ELEMENT(a, 0, 0); ELEMENT(r, 2, 0) = -ELEMENT(a, 1, 0); ELEMENT(r, 2, 1) = ELEMENT(a, 0, 0); ELEMENT(r, 2, 2) = 0; return matrix_autorelease(r); }