Datum aggr_InfoGain(PG_FUNCTION_ARGS) { ArrayType *state = PG_GETARG_ARRAYTYPE_P(0); int dimstate = ARR_NDIM(state); int *dimsstate = ARR_DIMS(state); int numstate = ArrayGetNItems(dimstate,dimsstate); float8 *vals_state=(float8 *)ARR_DATA_PTR(state); float8 truevalue = PG_GETARG_FLOAT8(1); float8 trueweight = PG_GETARG_FLOAT8(2); int32 posclasses = PG_GETARG_INT32(3); int32 trueclass = PG_GETARG_INT32(5); ArrayType *pgarray; vals_state[0] += trueweight; vals_state[trueclass] += trueweight; vals_state[(int)(truevalue*(posclasses+1))] += trueweight; vals_state[(int)(truevalue*(posclasses+1) + trueclass)] += trueweight; pgarray = construct_array((Datum *)vals_state, numstate,FLOAT8OID, sizeof(float8),true,'d'); PG_RETURN_ARRAYTYPE_P(pgarray); }
/* * regexp_split_to_array() * Split the string at matches of the pattern, returning the * split-out substrings as an array. */ Datum regexp_split_to_array(PG_FUNCTION_ARGS) { ArrayBuildState *astate = NULL; regexp_matches_ctx *splitctx; splitctx = setup_regexp_matches(PG_GETARG_TEXT_PP(0), PG_GETARG_TEXT_PP(1), PG_GETARG_TEXT_PP_IF_EXISTS(2), PG_GET_COLLATION(), true, false, true, true); while (splitctx->next_match <= splitctx->nmatches) { astate = accumArrayResult(astate, build_regexp_split_result(splitctx), false, TEXTOID, CurrentMemoryContext); splitctx->next_match++; } PG_RETURN_ARRAYTYPE_P(makeArrayResult(astate, CurrentMemoryContext)); }
Datum alpine_miner_nn_ca_o(PG_FUNCTION_ARGS) { ArrayType *weight_arg, *columns_arg, *input_range_arg, *input_base_arg,*hidden_node_number_arg, *result; Datum *weight_data, *columns_data, *input_range_data, *input_base_data, *hidden_node_number_data, *result_data; bool *weight_nulls, *columns_nulls, *input_range_nulls, *input_base_nulls, *hidden_node_number_nulls,*result_nulls; int weight_count, columns_count, input_range_count, input_base_count, hidden_node_number_count,result_count ; Oid result_eltype; int16 result_typlen; bool result_typbyval; char result_typalign; double output_range_arg,output_base_arg; int hidden_layer_number_arg, output_node_no_arg; bool normalize_arg, numerical_label_arg ; int ndims, *dims, *lbs; int i; int j; int k; int all_hidden_node_count; int weight_index; int hidden_node_number_index = 0; bool null_data; double * input; double * output; int * hidden_node_number; double *weight; double *hidden_node_output; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3) || PG_ARGISNULL(4) || PG_ARGISNULL(5) || PG_ARGISNULL(6) || PG_ARGISNULL(7) || PG_ARGISNULL(8) || PG_ARGISNULL(9) || PG_ARGISNULL(10)) { PG_RETURN_NULL(); } /* get weight_arg args */ weight_arg = PG_GETARG_ARRAYTYPE_P(0); null_data = alpine_miner_deconstruct_array(weight_arg, &weight_data, &weight_nulls,&weight_count); if (null_data) { PG_RETURN_NULL(); } columns_arg = PG_GETARG_ARRAYTYPE_P(1); null_data = alpine_miner_deconstruct_array(columns_arg, &columns_data, &columns_nulls,&columns_count); if (null_data) { PG_RETURN_NULL(); } /* get input_range_arg args */ input_range_arg = PG_GETARG_ARRAYTYPE_P(2); null_data = alpine_miner_deconstruct_array(input_range_arg, &input_range_data, &input_range_nulls,&input_range_count); if (null_data) { PG_RETURN_NULL(); } /* get input_base_arg args */ input_base_arg = PG_GETARG_ARRAYTYPE_P(3); null_data = alpine_miner_deconstruct_array(input_base_arg, &input_base_data, &input_base_nulls,&input_base_count); if (null_data) { PG_RETURN_NULL(); } /* get hidden_node_number_arg args */ hidden_node_number_arg = PG_GETARG_ARRAYTYPE_P(4); null_data = alpine_miner_deconstruct_array(hidden_node_number_arg, &hidden_node_number_data, &hidden_node_number_nulls,&hidden_node_number_count); if (null_data) { PG_RETURN_NULL(); } hidden_layer_number_arg= PG_GETARG_INT32(5); output_range_arg = PG_GETARG_FLOAT8(6); output_base_arg = PG_GETARG_FLOAT8(7); output_node_no_arg = PG_GETARG_INT32(8); normalize_arg = PG_GETARG_BOOL(9); numerical_label_arg = PG_GETARG_BOOL(10); #ifdef ALPINE_DEBUG elog(WARNING,"%f",DatumGetFloat8(columns_data[0])); #endif input = (double*)palloc(columns_count * sizeof(double));; output = (double*)palloc(output_node_no_arg * sizeof(double)); hidden_node_number = (int*) palloc(hidden_node_number_count * sizeof(int)); weight = (double*)palloc(weight_count * sizeof(double)); for (i = 0; i < weight_count; i++) { weight[i] = DatumGetFloat8(weight_data[i]); } all_hidden_node_count = 0; for (i = 0; i < hidden_layer_number_arg; i++) { hidden_node_number[i] = DatumGetInt32(hidden_node_number_data[i]); all_hidden_node_count += hidden_node_number[i]; } hidden_node_output = (double*)palloc(all_hidden_node_count * sizeof(double)); /* get output array element type */ result_eltype = FLOAT8OID; get_typlenbyvalalign(result_eltype, &result_typlen, &result_typbyval, &result_typalign); /* construct result array */ result_count = output_node_no_arg; result_data = (Datum *)palloc(result_count * sizeof(Datum)); result_nulls = (bool *)palloc(result_count * sizeof(bool)); for (i = 0; i < result_count; i++) { result_nulls[i] = false; } //caculate input if (normalize_arg) { i = 0; while (i < columns_count) { if (DatumGetFloat8(input_range_data[i]) != 0) { input[i] = ((DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i]))/DatumGetFloat8(input_range_data[i])); } else { input[i] = (DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i])); } #ifdef ALPINE_DEBUG elog(WARNING, "input:%f", input[i]); #endif i = i + 1; } } else { i = 0; while (i < columns_count) { input[i] = DatumGetFloat8(columns_data[i]); i = i + 1; } } // caculate hidden node output of 1st layer i = 0; while (i < hidden_node_number[0]) { hidden_node_output[i] = weight[0+i*(columns_count + 1)]; j = 0; while (j < columns_count) { hidden_node_output[i] = hidden_node_output[i]+input[j]*weight[1 + j + i *(columns_count + 1)]; #ifdef ALPINE_DEBUG elog(WARNING,"hiddensum[%d] input[%d] %f weight[%d] %f", i, j,input[j] , 1+j +(i)*(columns_count +1), weight[1+j +i*(columns_count + 1)]); #endif j = j + 1; } if (hidden_node_output[i] < -45.0) { hidden_node_output[i] = 0; } else if (hidden_node_output[i] > 45.0) { hidden_node_output[i] = 1; } else { hidden_node_output[i] = (1.0/(1.0+exp( -1.0 * hidden_node_output[i]))); } #ifdef ALPINE_DEBUG elog(WARNING,"hidden[%d] %f", i, hidden_node_output[i]); #endif i = i + 1; } // calculate hidden layer 2~last output weight_index = hidden_node_number[0] * (columns_count + 1) ; if (hidden_layer_number_arg > 1) { hidden_node_number_index = 0; i = 1; while (i < hidden_layer_number_arg ) { hidden_node_number_index = hidden_node_number_index + hidden_node_number[i - 1]; j = 0; while (j < hidden_node_number[i]) { hidden_node_output[hidden_node_number_index + j] = weight[weight_index + (hidden_node_number[i - 1] +1) * j]; k = 0; while (k < hidden_node_number[i - 1]) { hidden_node_output[hidden_node_number_index + j] = hidden_node_output[hidden_node_number_index + j]+hidden_node_output[hidden_node_number_index - hidden_node_number[i - 1] + k]*weight[weight_index + (hidden_node_number[i - 1] +1) * j + k + 1]; k = k + 1; } if (hidden_node_output[hidden_node_number_index + j] < -45.0) { hidden_node_output[hidden_node_number_index + j] = 0; } else if (hidden_node_output[hidden_node_number_index + j] > 45.0) { hidden_node_output[hidden_node_number_index + j] = 1; } else { hidden_node_output[hidden_node_number_index + j] = (1.0/(1+exp(-1.0*hidden_node_output[hidden_node_number_index+j]))); } j = j + 1; } weight_index = weight_index + hidden_node_number[i] * (hidden_node_number[i - 1] + 1); i = i + 1; } } //compute output value of output node; i = 0; while (i < output_node_no_arg) { output[i] = weight[weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i]; #ifdef ALPINE_DEBUG elog(WARNING,"weightindex:%d,weight[%d] %f",weight_index, weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i, output[i]); #endif j = 0; while (j < hidden_node_number[hidden_layer_number_arg-1]) { #ifdef ALPINE_DEBUG elog(WARNING,"ouput[%d]:%f ,hidden_node_number_index:%d,j:%d, weight[%d]:%f",i,output[i], hidden_node_number_index ,j,1+j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i , weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]); #endif output[i] = output[i]+hidden_node_output[hidden_node_number_index + j] * weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]; j = j + 1; } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum[%d] %f", i, output[i]); #endif if (numerical_label_arg) { output[i] = ((output[i]) * output_range_arg+output_base_arg); #ifdef ALPINE_DEBUG elog(WARNING,"output:%f, %f,%f",output[i],output_range_arg,output_base_arg); #endif } else { if (output[i] < -45.0) { output[i] = 0; } else if (output[i] > 45.0) { output[i] = 1; } else { output[i] = (1.0/(1+exp(-1.0*output[i]))); } } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum2[%d] %f", i, output[i]); #endif i = i + 1; } ndims = 1; dims = (int *) palloc(sizeof(int)); dims[0] = result_count; lbs = (int *) palloc(sizeof(int)); lbs[0] = 1; for (i = 0; i < output_node_no_arg; i++) { result_data[i] = Float8GetDatum(output[i]); #ifdef ALPINE_DEBUG elog(WARNING,"output[%d]:%f",i, output[i]); #endif } result = construct_md_array((void *)result_data, result_nulls, ndims, dims, lbs, result_eltype, result_typlen, result_typbyval, result_typalign); // pfree(result); pfree(weight_data); pfree(columns_data); pfree(input_range_data); pfree(input_base_data); pfree(hidden_node_number_data); pfree(result_data); pfree(weight_nulls); pfree(columns_nulls); pfree(input_range_nulls); pfree(input_base_nulls); pfree(hidden_node_number_nulls); pfree(result_nulls); pfree(input); pfree(output); pfree(lbs); pfree(dims); pfree(hidden_node_output); pfree(weight); pfree(hidden_node_number); PG_RETURN_ARRAYTYPE_P(result); }
/*----------------------------------------------------------------------------- * array_cat : * concatenate two nD arrays to form an nD array, or * push an (n-1)D array onto the end of an nD array *---------------------------------------------------------------------------- */ Datum array_cat(PG_FUNCTION_ARGS) { ArrayType *v1, *v2; ArrayType *result; int *dims, *lbs, ndims, nitems, ndatabytes, nbytes; int *dims1, *lbs1, ndims1, nitems1, ndatabytes1; int *dims2, *lbs2, ndims2, nitems2, ndatabytes2; int i; char *dat1, *dat2; bits8 *bitmap1, *bitmap2; Oid element_type; Oid element_type1; Oid element_type2; int32 dataoffset; /* Concatenating a null array is a no-op, just return the other input */ if (PG_ARGISNULL(0)) { if (PG_ARGISNULL(1)) PG_RETURN_NULL(); result = PG_GETARG_ARRAYTYPE_P(1); PG_RETURN_ARRAYTYPE_P(result); } if (PG_ARGISNULL(1)) { result = PG_GETARG_ARRAYTYPE_P(0); PG_RETURN_ARRAYTYPE_P(result); } v1 = PG_GETARG_ARRAYTYPE_P(0); v2 = PG_GETARG_ARRAYTYPE_P(1); element_type1 = ARR_ELEMTYPE(v1); element_type2 = ARR_ELEMTYPE(v2); /* Check we have matching element types */ if (element_type1 != element_type2) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with element types %s and %s are not " "compatible for concatenation.", format_type_be(element_type1), format_type_be(element_type2)))); /* OK, use it */ element_type = element_type1; /*---------- * We must have one of the following combinations of inputs: * 1) one empty array, and one non-empty array * 2) both arrays empty * 3) two arrays with ndims1 == ndims2 * 4) ndims1 == ndims2 - 1 * 5) ndims1 == ndims2 + 1 *---------- */ ndims1 = ARR_NDIM(v1); ndims2 = ARR_NDIM(v2); /* * short circuit - if one input array is empty, and the other is not, we * return the non-empty one as the result * * if both are empty, return the first one */ if (ndims1 == 0 && ndims2 > 0) PG_RETURN_ARRAYTYPE_P(v2); if (ndims2 == 0) PG_RETURN_ARRAYTYPE_P(v1); /* the rest fall under rule 3, 4, or 5 */ if (ndims1 != ndims2 && ndims1 != ndims2 - 1 && ndims1 != ndims2 + 1) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays of %d and %d dimensions are not " "compatible for concatenation.", ndims1, ndims2))); /* get argument array details */ lbs1 = ARR_LBOUND(v1); lbs2 = ARR_LBOUND(v2); dims1 = ARR_DIMS(v1); dims2 = ARR_DIMS(v2); dat1 = ARR_DATA_PTR(v1); dat2 = ARR_DATA_PTR(v2); bitmap1 = ARR_NULLBITMAP(v1); bitmap2 = ARR_NULLBITMAP(v2); nitems1 = ArrayGetNItems(ndims1, dims1); nitems2 = ArrayGetNItems(ndims2, dims2); ndatabytes1 = ARR_SIZE(v1) - ARR_DATA_OFFSET(v1); ndatabytes2 = ARR_SIZE(v2) - ARR_DATA_OFFSET(v2); if (ndims1 == ndims2) { /* * resulting array is made up of the elements (possibly arrays * themselves) of the input argument arrays */ ndims = ndims1; dims = (int *) palloc(ndims * sizeof(int)); lbs = (int *) palloc(ndims * sizeof(int)); dims[0] = dims1[0] + dims2[0]; lbs[0] = lbs1[0]; for (i = 1; i < ndims; i++) { if (dims1[i] != dims2[i] || lbs1[i] != lbs2[i]) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with differing element dimensions are " "not compatible for concatenation."))); dims[i] = dims1[i]; lbs[i] = lbs1[i]; } } else if (ndims1 == ndims2 - 1) { /* * resulting array has the second argument as the outer array, with * the first argument inserted at the front of the outer dimension */ ndims = ndims2; dims = (int *) palloc(ndims * sizeof(int)); lbs = (int *) palloc(ndims * sizeof(int)); memcpy(dims, dims2, ndims * sizeof(int)); memcpy(lbs, lbs2, ndims * sizeof(int)); /* increment number of elements in outer array */ dims[0] += 1; /* make sure the added element matches our existing elements */ for (i = 0; i < ndims1; i++) { if (dims1[i] != dims[i + 1] || lbs1[i] != lbs[i + 1]) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with differing dimensions are not " "compatible for concatenation."))); } } else { /* * (ndims1 == ndims2 + 1) * * resulting array has the first argument as the outer array, with the * second argument appended to the end of the outer dimension */ ndims = ndims1; dims = (int *) palloc(ndims * sizeof(int)); lbs = (int *) palloc(ndims * sizeof(int)); memcpy(dims, dims1, ndims * sizeof(int)); memcpy(lbs, lbs1, ndims * sizeof(int)); /* increment number of elements in outer array */ dims[0] += 1; /* make sure the added element matches our existing elements */ for (i = 0; i < ndims2; i++) { if (dims2[i] != dims[i + 1] || lbs2[i] != lbs[i + 1]) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with differing dimensions are not " "compatible for concatenation."))); } } /* Do this mainly for overflow checking */ nitems = ArrayGetNItems(ndims, dims); /* build the result array */ ndatabytes = ndatabytes1 + ndatabytes2; if (ARR_HASNULL(v1) || ARR_HASNULL(v2)) { dataoffset = ARR_OVERHEAD_WITHNULLS(ndims, nitems); nbytes = ndatabytes + dataoffset; } else { dataoffset = 0; /* marker for no null bitmap */ nbytes = ndatabytes + ARR_OVERHEAD_NONULLS(ndims); } result = (ArrayType *) palloc(nbytes); SET_VARSIZE(result, nbytes); result->ndim = ndims; result->dataoffset = dataoffset; result->elemtype = element_type; memcpy(ARR_DIMS(result), dims, ndims * sizeof(int)); memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int)); /* data area is arg1 then arg2 */ memcpy(ARR_DATA_PTR(result), dat1, ndatabytes1); memcpy(ARR_DATA_PTR(result) + ndatabytes1, dat2, ndatabytes2); /* handle the null bitmap if needed */ if (ARR_HASNULL(result)) { array_bitmap_copy(ARR_NULLBITMAP(result), 0, bitmap1, 0, nitems1); array_bitmap_copy(ARR_NULLBITMAP(result), nitems1, bitmap2, 0, nitems2); } PG_RETURN_ARRAYTYPE_P(result); }
/** * svec_return_array - returns an uncompressed Array */ Datum svec_return_array(PG_FUNCTION_ARGS) { SvecType *svec = PG_GETARG_SVECTYPE_P(0); ArrayType *pgarray = svec_return_array_internal(svec); PG_RETURN_ARRAYTYPE_P(pgarray); }
Datum hvault_table_count_step(PG_FUNCTION_ARGS) { MemoryContext aggmemctx, oldmemctx; ArrayType * ctx; ArrayType * idx_array; int i, pos_idx; int32_t * ctx_data; if (!AggCheckCallContext(fcinfo, &aggmemctx)) elog(ERROR, "hvault_table_group_step called in non-aggregate context"); ctx = PG_ARGISNULL(0) ? NULL : PG_GETARG_ARRAYTYPE_P(0); if (ctx == NULL) { int ndim; int32_t * bounds_data; int dims[MAXDIM]; int lbs[MAXDIM]; ArrayType * bounds_array; oldmemctx = MemoryContextSwitchTo(aggmemctx); if (PG_ARGISNULL(2)) elog(ERROR, "bounds array must not be null"); // if (!get_fn_expr_arg_stable(fcinfo->flinfo, 2)) // elog(ERROR, "bounds array must be const"); bounds_array = PG_GETARG_ARRAYTYPE_P(2); Assert(bounds_array != NULL); Assert(bounds_array->elemtype == INT4OID); if (bounds_array->ndim != 2 || ARR_DIMS(bounds_array)[1] != 2) elog(ERROR, "bounds array size is invalid"); if (ARR_HASNULL(bounds_array)) { int size = ARR_DIMS(bounds_array)[0] * ARR_DIMS(bounds_array)[1]; for (i = 0; i < (size + 7) / 8; i++) if (ARR_NULLBITMAP(bounds_array)[i] != 0) elog(ERROR, "bounds array must not contain NULLs"); } ndim = ARR_DIMS(bounds_array)[0]; if (ndim > MAXDIM) elog(ERROR, "too many dimensions, max supported is %d", MAXDIM); bounds_data = (int32_t *) ARR_DATA_PTR(bounds_array); for (i = 0; i < ndim; i++) { int ubs; lbs[i] = bounds_data[2*i]; ubs = bounds_data[2*i+1]; dims[i] = ubs - lbs[i]; } ctx = intArrayInit(ndim, dims, lbs); MemoryContextSwitchTo(oldmemctx); } Assert(!ARR_HASNULL(ctx)); Assert(ctx->elemtype == INT4OID); if (PG_ARGISNULL(1)) elog(ERROR, "group index array must not be null"); idx_array = PG_GETARG_ARRAYTYPE_P(1); Assert(idx_array != NULL); Assert(idx_array->elemtype == INT4OID); if (idx_array->ndim != 1) elog(ERROR, "group index array must have single dimension"); if (ARR_DIMS(idx_array)[0] != ctx->ndim) elog(ERROR, "group index array length is inconsistent"); if (ARR_HASNULL(idx_array)) { int size = ARR_DIMS(idx_array)[0]; for (i = 0; i < (size + 7) / 8; i++) /* Skip elements with nulls */ if (ARR_NULLBITMAP(idx_array)[i] != 0) { elog(WARNING, "index array contains NULL, skipping"); PG_RETURN_ARRAYTYPE_P(ctx); } } pos_idx = intArrayIdx(ctx, (int *) ARR_DATA_PTR(idx_array), true); if (pos_idx != -1) { Assert(pos_idx >= 0); if (ARR_SIZE(ctx) - ARR_DATA_OFFSET(ctx) <= pos_idx * 4) { elog(ERROR, "Array out of bounds access: %ld %d", ARR_SIZE(ctx) - ARR_DATA_OFFSET(ctx), pos_idx * 4); } ctx_data = (int32_t *) ARR_DATA_PTR(ctx); ctx_data[pos_idx]++; } PG_RETURN_ARRAYTYPE_P(ctx); }
/*! * scalar function taking an mfv sketch, returning a histogram of * its most frequent values */ Datum __mfvsketch_final(PG_FUNCTION_ARGS) { bytea * transblob = PG_GETARG_BYTEA_P(0); mfvtransval *transval = NULL; ArrayType * retval; uint32 i; int dims[2], lbs[2]; /* Oid typInput, typIOParam; */ Oid outFuncOid; bool typIsVarlena; int16 typlen; bool typbyval; char typalign; char typdelim; Oid typioparam; Oid typiofunc; if (PG_ARGISNULL(0)) PG_RETURN_NULL(); if (VARSIZE(transblob) < MFV_TRANSVAL_SZ(0)) PG_RETURN_NULL(); check_mfvtransval(transblob); transval = (mfvtransval *)VARDATA(transblob); /* * We only declare the variable-length array histo here after some sanity * checking. We risk a stack overflow otherwise. In particular, we need to * make sure that transval->max_mfvs is initialized. It might not be if the * (strict) transition function is never called. (MADLIB-254) */ Datum histo[transval->max_mfvs][2]; qsort(transval->mfvs, transval->next_mfv, sizeof(offsetcnt), cnt_cmp_desc); getTypeOutputInfo(INT8OID, &outFuncOid, &typIsVarlena); for (i = 0; i < transval->next_mfv; i++) { void *tmpp = mfv_transval_getval(transblob,i); Datum curval = PointerExtractDatum(tmpp, transval->typByVal); char *countbuf = OidOutputFunctionCall(outFuncOid, Int64GetDatum(transval->mfvs[i].cnt)); char *valbuf = OidOutputFunctionCall(transval->outFuncOid, curval); histo[i][0] = PointerGetDatum(cstring_to_text(valbuf)); histo[i][1] = PointerGetDatum(cstring_to_text(countbuf)); pfree(countbuf); pfree(valbuf); } /* * Get info about element type */ get_type_io_data(TEXTOID, IOFunc_output, &typlen, &typbyval, &typalign, &typdelim, &typioparam, &typiofunc); dims[0] = i; dims[1] = 2; lbs[0] = lbs[1] = 0; retval = construct_md_array((Datum *)histo, NULL, 2, dims, lbs, TEXTOID, -1, 0, 'i'); PG_RETURN_ARRAYTYPE_P(retval); }
Datum alpine_miner_lr_combine(PG_FUNCTION_ARGS) { ArrayType *state1, *state2, *result; float8 *state1Data, *state2Data, *resultData; int i, size; int statelen; if (PG_ARGISNULL(0)) { if (PG_ARGISNULL(1)) PG_RETURN_NULL(); PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(1)); } if (PG_ARGISNULL(1)) PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(0)); state1 = PG_GETARG_ARRAYTYPE_P(0); state2 = PG_GETARG_ARRAYTYPE_P(1); if (ARR_NULLBITMAP(state1) || ARR_NULLBITMAP(state2) || ARR_NDIM(state1) != 1 || ARR_NDIM(state2) != 1 || ARR_ELEMTYPE(state1) != FLOAT8OID || ARR_ELEMTYPE(state2) != FLOAT8OID) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); } if (ARR_DIMS(state1)[0] == 1) PG_RETURN_ARRAYTYPE_P(state2); if (ARR_DIMS(state2)[0] == 1) PG_RETURN_ARRAYTYPE_P(state1); state1Data = (float8*) ARR_DATA_PTR(state1); state2Data = (float8*) ARR_DATA_PTR(state2); if (ARR_DIMS(state1)[0] != ARR_DIMS(state2)[0]) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)), errdetail("The independent-variable array is not of constant width."))); } statelen = ARR_DIMS(state1)[0]; size = statelen * sizeof(float8) + ARR_OVERHEAD_NONULLS(1); result = (ArrayType *) palloc(size); SET_VARSIZE(result, size); result->ndim = 1; result->dataoffset = 0; result->elemtype = FLOAT8OID; ARR_DIMS(result)[0] = statelen; ARR_LBOUND(result)[0] = 1; resultData = (float8*) ARR_DATA_PTR(result); memset(resultData, 0, statelen * sizeof(float8)); for (i = 0; i < statelen; i++){ resultData[i] = state1Data[i] + state2Data[i]; } PG_RETURN_ARRAYTYPE_P(result); }
Datum float8arr_cast_int4(PG_FUNCTION_ARGS) { float8 value=(float8 )PG_GETARG_INT32(0); PG_RETURN_ARRAYTYPE_P(svec_return_array_internal(svec_make_scalar(value,1))); }
Datum pseudoinverse(PG_FUNCTION_ARGS) { /* * A note on types: PostgreSQL array dimensions are of type int. See, e.g., * the macro definition ARR_DIMS */ int rows, columns; float8 *A, *Aplus; ArrayType *A_PG, *Aplus_PG; int lbs[2], dims[2]; /* * Perform all the error checking needed to ensure that no one is * trying to call this in some sort of crazy way. */ if (PG_NARGS() != 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pseudoinverse called with %d arguments", PG_NARGS()))); } if (PG_ARGISNULL(0)) PG_RETURN_NULL(); A_PG = PG_GETARG_ARRAYTYPE_P(0); if (ARR_ELEMTYPE(A_PG) != FLOAT8OID) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pseudoinverse only defined over float8[]"))); if (ARR_NDIM(A_PG) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("pseudoinverse only defined over 2 dimensional arrays")) ); if (ARR_NULLBITMAP(A_PG)) ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("null array element not allowed in this context"))); /* Extract rows, columns, and data */ rows = ARR_DIMS(A_PG)[0]; columns = ARR_DIMS(A_PG)[1]; A = (float8 *) ARR_DATA_PTR(A_PG); /* Allocate a PG array for the result, "Aplus" is A+, the pseudo inverse of A */ lbs[0] = 1; lbs[1] = 1; dims[0] = columns; dims[1] = rows; Aplus_PG = construct_md_array(NULL, NULL, 2, dims, lbs, FLOAT8OID, sizeof(float8), true, 'd'); Aplus = (float8 *) ARR_DATA_PTR(Aplus_PG); pinv(rows,columns,A,Aplus); PG_RETURN_ARRAYTYPE_P(Aplus_PG); }
Datum fft_agg_finalfn(PG_FUNCTION_ARGS) { ArrayType *input, *result = NULL; Oid eltype; int16 typlen; bool typbyval; char typalign; Datum *data; int i, n; int ndims, *dims; kiss_fft_cfg cfg; kiss_fft_cpx *cx_in = NULL, *cx_out = NULL; if (!AggCheckCallContext(fcinfo, NULL)) elog(ERROR, "fft_agg_finalfn() Not aggregate context"); if (PG_ARGISNULL(0)) elog(ERROR, "fft_agg_finalfn() args cannot be null"); /* elog(INFO, "fft_agg_finalfn() nargs: %d", PG_NARGS()); */ /* elog(INFO, "p1 %p", PG_GETARG_POINTER(0)); */ /* state array */ input = PG_GETARG_ARRAYTYPE_P(0); /* elog(INFO, "arg 0 array type: 0x%p", input); */ /* get various pieces of data from the input array */ ndims = ARR_NDIM(input); dims = ARR_DIMS(input); eltype = ARR_ELEMTYPE(input); /* elog(INFO, "input ndims: %d dims: %d elemtype: %d", ndims, *dims, eltype); */ Assert(ndims == 1); Assert(eltype == FLOAT4OID); /* get input array element type */ get_typlenbyvalalign(eltype, &typlen, &typbyval, &typalign); /* elog(INFO, "olen: %d obyval: %d align: %d", typlen, typbyval, typalign); */ /* get src data */ deconstruct_array(input, eltype, typlen, typbyval, typalign, &data, NULL, &n); /* elog(INFO, "idata: %p n: %d", data, n); */ Assert(*dims == n); cx_in = palloc0(*dims * sizeof(kiss_fft_cpx)); cx_out = palloc0(*dims * sizeof(kiss_fft_cpx)); /* apply scale */ for (i=0; i<*dims; i++) { cx_in[i].r = DatumGetFloat4(data[i]); /* elog(INFO, "%d %f %f", i, DatumGetFloat4(data[i]), cx_in[i].i); */ } if ((cfg = kiss_fft_alloc(*dims, 0, 0, 0)) == NULL) elog(ERROR, "kiss_fft_alloc() failed"); kiss_fft(cfg, cx_in, cx_out); for (i=0; i<*dims; i++) { ((float *)data)[i] = (cx_out[i].r * cx_out[i].r + cx_out[i].i * cx_out[i].i) / ((double)*dims); /* printf("%23.15e %23.15e\n", freq / (double)n * (double)i, (cx_out[i].r * cx_out[i].r + cx_out[i].i * cx_out[i].i) / (double)n); */ /* elog(INFO, "data %d %f", i, (double)(data[i])); */ } /* elog(INFO, "odata: %p dims: %d otype: %d olen: %d obyval: %d align: %d", data, *dims, eltype, typlen, typbyval, typalign); */ result = construct_array((void *)data, *dims, eltype, typlen, typbyval, typalign); free(cfg); pfree(data); pfree(cx_in); pfree(cx_out); PG_RETURN_ARRAYTYPE_P(result); }
/* * Preliminary segment-level calculation function for multi-linear regression * aggregates. */ Datum float8_mregr_combine(PG_FUNCTION_ARGS) { ArrayType *state1, *state2, *result; float8 *state1Data, *state2Data, *resultData; uint32 len; uint64 statelen, i; Size size; /* We should be strict, but it doesn't hurt to be paranoid */ if (PG_ARGISNULL(0)) { if (PG_ARGISNULL(1)) PG_RETURN_NULL(); PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(1)); } if (PG_ARGISNULL(1)) PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(0)); state1 = PG_GETARG_ARRAYTYPE_P(0); state2 = PG_GETARG_ARRAYTYPE_P(1); /* Ensure that both arrays are single dimensional float8[] arrays */ if (ARR_NULLBITMAP(state1) || ARR_NULLBITMAP(state2) || ARR_NDIM(state1) != 1 || ARR_NDIM(state2) != 1 || ARR_ELEMTYPE(state1) != FLOAT8OID || ARR_ELEMTYPE(state2) != FLOAT8OID) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); } /* * Remember that we initialized to {0}, so if either array is still at * the initial value then just return the other one */ if (ARR_DIMS(state1)[0] == 1) PG_RETURN_ARRAYTYPE_P(state2); if (ARR_DIMS(state2)[0] == 1) PG_RETURN_ARRAYTYPE_P(state1); state1Data = (float8*) ARR_DATA_PTR(state1); state2Data = (float8*) ARR_DATA_PTR(state2); if (ARR_DIMS(state1)[0] != ARR_DIMS(state2)[0] || state1Data[0] != state2Data[0]) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)), errdetail("The independent-variable array is not of constant width."))); } len = state1Data[0]; statelen = STATE_LEN(len); /* * Violation of any of the following conditions indicates bogus inputs. */ if (state1Data[0] > UINT32_MAX || (uint64) ARR_DIMS(state1)[0] != statelen || !IS_FEASIBLE_STATE_LEN(statelen)) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("preliminary segment-level calculation function \"%s\" called with invalid parameters", format_procedure(fcinfo->flinfo->fn_oid)))); } /* Validations pass, allocate memory for result and do work */ /* * Precondition: * IS_FEASIBLE_STATE_LEN(statelen) */ size = statelen * sizeof(float8) + ARR_OVERHEAD_NONULLS(1); result = (ArrayType *) palloc(size); SET_VARSIZE(result, size); result->ndim = 1; result->dataoffset = 0; result->elemtype = FLOAT8OID; ARR_DIMS(result)[0] = statelen; ARR_LBOUND(result)[0] = 1; resultData = (float8*) ARR_DATA_PTR(result); memset(resultData, 0, statelen * sizeof(float8)); /* * Contents of 'state' are as follows: * [0] = len(X[]) * [1] = count * [2] = sum(y) * [3] = sum(y*y) * [4:N] = sum(X'[] * y) * [N+1:M] = sum(X[] * X'[]) * N = 3 + len(X) * M = N + len(X)*len(X) */ resultData[0] = len; for (i = 1; i < statelen; i++) resultData[i] = state1Data[i] + state2Data[i]; PG_RETURN_ARRAYTYPE_P(result); }
/* * The pre-function for REP. It takes two class count arrays * produced by the sfunc and combine them together. * * Parameters: * 1 arg: The array returned by sfun1 * 2 arg: The array returned by sfun2 * Return: * The array with the combined information */ Datum rep_aggr_class_count_prefunc(PG_FUNCTION_ARGS) { ArrayType *class_count_array = NULL; int array_dim = 0; int *p_array_dim = NULL; int array_length = 0; int64 *class_count_data = NULL; ArrayType *class_count_array2 = NULL; int array_dim2 = 0; int *p_array_dim2 = NULL; int array_length2 = 0; int64 *class_count_data2 = NULL; if (PG_ARGISNULL(0) && PG_ARGISNULL(1)) PG_RETURN_NULL(); else if (PG_ARGISNULL(1) || PG_ARGISNULL(0)) { /* If one of the two array is null, just return the non-null array directly */ PG_RETURN_ARRAYTYPE_P(PG_ARGISNULL(1) ? PG_GETARG_ARRAYTYPE_P(0) : PG_GETARG_ARRAYTYPE_P(1)); } else { /* * If both arrays are not null, we will merge them together. */ if (fcinfo->context && IsA(fcinfo->context, AggState)) class_count_array = PG_GETARG_ARRAYTYPE_P(0); else class_count_array = PG_GETARG_ARRAYTYPE_P_COPY(0); check_error ( class_count_array, "invalid aggregation state array" ); array_dim = ARR_NDIM(class_count_array); check_error_value ( array_dim == 1, "invalid array dimension: %d. The dimension of class count array must be equal to 1", array_dim ); p_array_dim = ARR_DIMS(class_count_array); array_length = ArrayGetNItems(array_dim,p_array_dim); class_count_data = (int64 *)ARR_DATA_PTR(class_count_array); class_count_array2 = PG_GETARG_ARRAYTYPE_P(1); array_dim2 = ARR_NDIM(class_count_array2); check_error_value ( array_dim2 == 1, "invalid array dimension: %d. The dimension of class count array must be equal to 1", array_dim2 ); p_array_dim2 = ARR_DIMS(class_count_array2); array_length2 = ArrayGetNItems(array_dim2,p_array_dim2); class_count_data2 = (int64 *)ARR_DATA_PTR(class_count_array2); check_error ( array_length == array_length2, "the size of the two array must be the same in prefunction" ); for (int index = 0; index < array_length; index++) class_count_data[index] += class_count_data2[index]; PG_RETURN_ARRAYTYPE_P(class_count_array); } }
/* * The step function for aggregating the class counts while doing Reduce Error Pruning (REP). * * Parameters: * class_count_array The array used to store the accumulated information. * [0]: the total number of mis-classified cases * [i]: the number of cases belonging to the ith class * classified_class The predicted class based on our trained DT model. * original_class The real class value provided in the validation set. * max_num_of_classes The total number of distinct class values. * Return: * An updated state array. */ Datum rep_aggr_class_count_sfunc(PG_FUNCTION_ARGS) { ArrayType *class_count_array = NULL; int array_dim = 0; int *p_array_dim = NULL; int array_length = 0; int64 *class_count_data = NULL; int classified_class = PG_GETARG_INT32(1); int original_class = PG_GETARG_INT32(2); int max_num_of_classes = PG_GETARG_INT32(3); bool need_reconstruct_array = false; check_error_value ( max_num_of_classes >= 2, "invalid value: %d. The number of classes must be greater than or equal to 2", max_num_of_classes ); check_error_value ( original_class > 0 && original_class <= max_num_of_classes, "invalid real class value: %d. It must be in range from 1 to the number of classes", original_class ); check_error_value ( classified_class > 0 && classified_class <= max_num_of_classes, "invalid classified class value: %d. It must be in range from 1 to the number of classes", classified_class ); /* test if the first argument (class count array) is null */ if (PG_ARGISNULL(0)) { /* * We assume the maximum number of classes is limited (up to millions), * so that the allocated array won't break our memory limitation. */ class_count_data = palloc0(sizeof(int64) * (max_num_of_classes + 1)); array_length = max_num_of_classes + 1; need_reconstruct_array = true; } else { if (fcinfo->context && IsA(fcinfo->context, AggState)) class_count_array = PG_GETARG_ARRAYTYPE_P(0); else class_count_array = PG_GETARG_ARRAYTYPE_P_COPY(0); check_error ( class_count_array, "invalid aggregation state array" ); array_dim = ARR_NDIM(class_count_array); check_error_value ( array_dim == 1, "invalid array dimension: %d. The dimension of class count array must be equal to 1", array_dim ); p_array_dim = ARR_DIMS(class_count_array); array_length = ArrayGetNItems(array_dim,p_array_dim); class_count_data = (int64 *)ARR_DATA_PTR(class_count_array); check_error_value ( array_length == max_num_of_classes + 1, "invalid array length: %d. The length of class count array must be equal to the total number classes + 1", array_length ); } /* * If the condition is met, then the current record has been mis-classified. * Therefore, we will need to increase the first element. */ if(original_class != classified_class) ++class_count_data[0]; /* In any case, we will update the original class count */ ++class_count_data[original_class]; if( need_reconstruct_array ) { /* construct a new array to keep the aggr states. */ class_count_array = construct_array( (Datum *)class_count_data, array_length, INT8OID, sizeof(int64), true, 'd' ); } PG_RETURN_ARRAYTYPE_P(class_count_array); }
/*----------------------------------------------------------------------------- * array_push : * push an element onto either end of a one-dimensional array *---------------------------------------------------------------------------- */ Datum array_push(PG_FUNCTION_ARGS) { ArrayType *v; Datum newelem; int *dimv, *lb; ArrayType *result; int indx; bool isNull; Oid element_type; int16 typlen; bool typbyval; char typalign; Oid arg0_typeid = get_fn_expr_argtype(fcinfo->flinfo, 0); Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1); Oid arg0_elemid; Oid arg1_elemid; ArrayMetaState *my_extra; if (arg0_typeid == InvalidOid || arg1_typeid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data types"))); arg0_elemid = get_element_type(arg0_typeid); arg1_elemid = get_element_type(arg1_typeid); if (arg0_elemid != InvalidOid) { v = PG_GETARG_ARRAYTYPE_P(0); element_type = ARR_ELEMTYPE(v); newelem = PG_GETARG_DATUM(1); } else if (arg1_elemid != InvalidOid) { v = PG_GETARG_ARRAYTYPE_P(1); element_type = ARR_ELEMTYPE(v); newelem = PG_GETARG_DATUM(0); } else { /* Shouldn't get here given proper type checking in parser */ ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("neither input type is an array"))); PG_RETURN_NULL(); /* keep compiler quiet */ } if (ARR_NDIM(v) == 1) { lb = ARR_LBOUND(v); dimv = ARR_DIMS(v); if (arg0_elemid != InvalidOid) { /* append newelem */ int ub = dimv[0] + lb[0] - 1; indx = ub + 1; } else { /* prepend newelem */ indx = lb[0] - 1; } } else if (ARR_NDIM(v) == 0) indx = 1; else ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("argument must be empty or one-dimensional array"))); /* * We arrange to look up info about element type only once per series * of calls, assuming the element type doesn't change underneath us. */ my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; if (my_extra == NULL) { fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(ArrayMetaState)); my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; my_extra->element_type = InvalidOid; } if (my_extra->element_type != element_type) { /* Get info about element type */ get_typlenbyvalalign(element_type, &my_extra->typlen, &my_extra->typbyval, &my_extra->typalign); my_extra->element_type = element_type; } typlen = my_extra->typlen; typbyval = my_extra->typbyval; typalign = my_extra->typalign; result = array_set(v, 1, &indx, newelem, -1, typlen, typbyval, typalign, &isNull); PG_RETURN_ARRAYTYPE_P(result); }
Datum alpine_miner_nn_ca_change(PG_FUNCTION_ARGS) { ArrayType *weight_arg, *columns_arg, *input_range_arg, *input_base_arg,*hidden_node_number_arg, *result; Datum *weight_data, *columns_data, *input_range_data, *input_base_data, *hidden_node_number_data, *result_data; bool *weight_nulls, *columns_nulls, *input_range_nulls, *input_base_nulls, *hidden_node_number_nulls,*result_nulls; int weight_count, columns_count, input_range_count, input_base_count, hidden_node_number_count,result_count ; Oid result_eltype; int16 result_typlen; bool result_typbyval; char result_typalign; double output_range_arg,output_base_arg, learning_rate_ar, label_arg; int hidden_layer_number_arg, output_node_no_arg, set_size_arg; bool normalize_arg, numerical_label_arg ; int ndims, *dims, *lbs; int i; int j; int k; int all_hidden_node_count; int weight_index; int hidden_node_number_index = 0; bool null_data; double * input; double * output; int * hidden_node_number; double *weight; double *hidden_node_output; double delta = 0.0; double total_error = 0.0; double * output_error; double direct_output_error = 0.0; double * hidden_node_error; double error_sum = 0.0; double current_change = 0.0; double threshold_change = 0.0; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3) || PG_ARGISNULL(4) || PG_ARGISNULL(5) || PG_ARGISNULL(6) || PG_ARGISNULL(7) || PG_ARGISNULL(8) || PG_ARGISNULL(9) || PG_ARGISNULL(10) || PG_ARGISNULL(11) || PG_ARGISNULL(12)){ PG_RETURN_NULL(); } /* get weight_arg args */ weight_arg = PG_GETARG_ARRAYTYPE_P(0); null_data = alpine_miner_deconstruct_array(weight_arg, &weight_data, &weight_nulls,&weight_count); if (null_data) { PG_RETURN_NULL(); } columns_arg = PG_GETARG_ARRAYTYPE_P(1); null_data = alpine_miner_deconstruct_array(columns_arg, &columns_data, &columns_nulls,&columns_count); if (null_data) { PG_RETURN_NULL(); } /* get input_range_arg args */ input_range_arg = PG_GETARG_ARRAYTYPE_P(2); null_data = alpine_miner_deconstruct_array(input_range_arg, &input_range_data, &input_range_nulls,&input_range_count); if (null_data) { PG_RETURN_NULL(); } /* get input_base_arg args */ input_base_arg = PG_GETARG_ARRAYTYPE_P(3); null_data = alpine_miner_deconstruct_array(input_base_arg, &input_base_data, &input_base_nulls,&input_base_count); if (null_data) { PG_RETURN_NULL(); } /* get hidden_node_number_arg args */ hidden_node_number_arg = PG_GETARG_ARRAYTYPE_P(4); null_data = alpine_miner_deconstruct_array(hidden_node_number_arg, &hidden_node_number_data, &hidden_node_number_nulls,&hidden_node_number_count); if (null_data) { PG_RETURN_NULL(); } hidden_layer_number_arg= PG_GETARG_INT32(5); output_range_arg = PG_GETARG_FLOAT8(6); output_base_arg = PG_GETARG_FLOAT8(7); output_node_no_arg = PG_GETARG_INT32(8); normalize_arg = PG_GETARG_BOOL(9); numerical_label_arg = PG_GETARG_BOOL(10); label_arg = PG_GETARG_FLOAT8(11); set_size_arg = PG_GETARG_INT32(12); if (set_size_arg <= 0) { set_size_arg = 1; } #ifdef ALPINE_DEBUG elog(WARNING,"%f",DatumGetFloat8(columns_data[0])); #endif input = (double*)palloc(columns_count * sizeof(double));; output = (double*)palloc(output_node_no_arg * sizeof(double)); hidden_node_number = (int*) palloc(hidden_node_number_count * sizeof(int)); weight = (double*)palloc(weight_count * sizeof(double)); for (i = 0; i < weight_count; i++) { weight[i] = DatumGetFloat8(weight_data[i]); } all_hidden_node_count = 0; for (i = 0; i < hidden_layer_number_arg; i++) { hidden_node_number[i] = DatumGetInt32(hidden_node_number_data[i]); all_hidden_node_count += hidden_node_number[i]; } hidden_node_output = (double*)palloc(all_hidden_node_count * sizeof(double)); //caculate input if (normalize_arg) { i = 0; while (i < columns_count) { if (DatumGetFloat8(input_range_data[i]) != 0) { input[i] = ((DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i]))/DatumGetFloat8(input_range_data[i])); } else { input[i] = (DatumGetFloat8(columns_data[i])-DatumGetFloat8(input_base_data[i])); } #ifdef ALPINE_DEBUG elog(WARNING, "input:%f", input[i]); #endif i = i + 1; } } else { i = 0; while (i < columns_count) { input[i] = DatumGetFloat8(columns_data[i]); i = i + 1; } } // caculate hidden node output of 1st layer i = 0; while (i < hidden_node_number[0]) { hidden_node_output[i] = weight[0+i*(columns_count + 1)]; j = 0; while (j < columns_count) { hidden_node_output[i] = hidden_node_output[i]+input[j]*weight[1 + j + i *(columns_count + 1)]; #ifdef ALPINE_DEBUG elog(WARNING,"hiddensum[%d] input[%d] %f weight[%d] %f", i, j,input[j] , 1+j +(i)*(columns_count +1), weight[1+j +i*(columns_count + 1)]); #endif j = j + 1; } if (hidden_node_output[i] < -45.0) { hidden_node_output[i] = 0; } else if (hidden_node_output[i] > 45.0) { hidden_node_output[i] = 1; } else { hidden_node_output[i] = (1.0/(1.0+exp( -1.0 * hidden_node_output[i]))); } #ifdef ALPINE_DEBUG elog(WARNING,"hidden[%d] %f", i, hidden_node_output[i]); #endif i = i + 1; } // calculate hidden layer 2~last output weight_index = hidden_node_number[0] * (columns_count + 1) ; if (hidden_layer_number_arg > 1) { hidden_node_number_index = 0; i = 1; while (i < hidden_layer_number_arg ) { hidden_node_number_index = hidden_node_number_index + hidden_node_number[i - 1]; j = 0; while (j < hidden_node_number[i]) { hidden_node_output[hidden_node_number_index + j] = weight[weight_index + (hidden_node_number[i - 1] +1) * j]; k = 0; while (k < hidden_node_number[i - 1]) { hidden_node_output[hidden_node_number_index + j] = hidden_node_output[hidden_node_number_index + j]+hidden_node_output[hidden_node_number_index - hidden_node_number[i - 1] + k]*weight[weight_index + (hidden_node_number[i - 1] +1) * j + k + 1]; k = k + 1; } if (hidden_node_output[hidden_node_number_index + j] < -45.0) { hidden_node_output[hidden_node_number_index + j] = 0; } else if (hidden_node_output[hidden_node_number_index + j] > 45.0) { hidden_node_output[hidden_node_number_index + j] = 1; } else { hidden_node_output[hidden_node_number_index + j] = (1.0/(1+exp(-1.0*hidden_node_output[hidden_node_number_index+j]))); } j = j + 1; } weight_index = weight_index + hidden_node_number[i] * (hidden_node_number[i - 1] + 1); i = i + 1; } } //compute output value of output node; i = 0; while (i < output_node_no_arg) { output[i] = weight[weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i]; #ifdef ALPINE_DEBUG elog(WARNING,"weightindex:%d,weight[%d] %f",weight_index, weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i, output[i]); #endif j = 0; while (j < hidden_node_number[hidden_layer_number_arg-1]) { #ifdef ALPINE_DEBUG elog(WARNING,"ouput[%d]:%f ,hidden_node_number_index:%d,j:%d, weight[%d]:%f",i,output[i], hidden_node_number_index ,j,1+j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i , weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]); #endif output[i] = output[i]+hidden_node_output[hidden_node_number_index + j] * weight[1 + j + weight_index + (hidden_node_number[hidden_layer_number_arg-1]+1) * i ]; j = j + 1; } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum[%d] %f", i, output[i]); #endif if (numerical_label_arg) { output[i] = ((output[i]) * output_range_arg+output_base_arg); #ifdef ALPINE_DEBUG elog(WARNING,"output:%f, %f,%f",output[i],output_range_arg,output_base_arg); #endif } else { if (output[i] < -45.0) { output[i] = 0; } else if (output[i] > 45.0) { output[i] = 1; } else { output[i] = (1.0/(1+exp(-1.0*output[i]))); } } #ifdef ALPINE_DEBUG elog(WARNING,"ouputsum2[%d] %f", i, output[i]); #endif i = i + 1; } /* get output array element type */ result_eltype = FLOAT8OID; get_typlenbyvalalign(result_eltype, &result_typlen, &result_typbyval, &result_typalign); /* construct result array */ result_count = weight_count + 1; result_data = (Datum *)palloc(result_count * sizeof(Datum)); result_nulls = (bool *)palloc(result_count * sizeof(bool)); for (i = 0; i < result_count; i++) { result_nulls[i] = false; } //compute error of output node output_error = (double *)palloc(output_node_no_arg * sizeof(double)); for(i = 0; i < output_node_no_arg; i++) { if(numerical_label_arg) { if (output_range_arg == 0.0) { direct_output_error = 0.0; } else { direct_output_error = (label_arg - output[i])/output_range_arg; } output_error[i] = direct_output_error; } else { if (((int)label_arg) == i) { direct_output_error = 1.0 - output[i]; } else { direct_output_error = 0.0 - output[i]; } #ifdef ALPINE_DEBUG elog(WARNING,"label_arg :%f %d %d", label_arg, i, (((int)label_arg) == i)); #endif output_error[i] = direct_output_error * output[i] * (1- output[i]); } total_error += direct_output_error*direct_output_error; #ifdef ALPINE_DEBUG elog(WARNING,"output_error[%d] %f totalerror:%f", i, output_error[i], total_error); #endif } //compute hidden_node_error of last layer hidden_node---- hidden_node_error = (double*)palloc(all_hidden_node_count * sizeof(double)); weight_index = weight_count - output_node_no_arg*(hidden_node_number[hidden_layer_number_arg - 1] + 1) ; hidden_node_number_index = all_hidden_node_count - hidden_node_number[hidden_layer_number_arg - 1]; for(i = 0; i < hidden_node_number[hidden_layer_number_arg - 1]; i++) { error_sum = 0.0; for(k = 0; k < output_node_no_arg; k++) { error_sum = error_sum+output_error[k]*weight[weight_index + (hidden_node_number[hidden_layer_number_arg - 1] + 1)*k + i + 1]; #ifdef ALPINE_DEBUG elog(WARNING,"output_error[%d]:%f,weight[%d]:%f",k,output_error[k],weight_index + (hidden_node_number[hidden_layer_number_arg - 1] + 1)*k + i + 1, weight[weight_index + (hidden_node_number[hidden_layer_number_arg - 1] + 1)*k + i + 1]); #endif } hidden_node_error[hidden_node_number_index + i] = error_sum*hidden_node_output[hidden_node_number_index + i]*(1.0-hidden_node_output[hidden_node_number_index + i]); #ifdef ALPINE_DEBUG elog(WARNING,"hidden_node_error[%d] %f ", hidden_node_number_index+i, hidden_node_error[hidden_node_number_index + i]); #endif } //compute hidden_node_error of 1 layer to the one before last layer hidden node if (hidden_layer_number_arg > 1) { weight_index = weight_index - (hidden_node_number[hidden_layer_number_arg - 2] + 1)*hidden_node_number[hidden_layer_number_arg - 1]; hidden_node_number_index = hidden_node_number_index - hidden_node_number[hidden_layer_number_arg - 2]; for(i = hidden_layer_number_arg - 2; i >= 0; i--) { for(j = 0; j < hidden_node_number[i]; j++) { error_sum = 0.0; for (k = 0; k < hidden_node_number[i + 1]; k++) { error_sum = error_sum+hidden_node_error[hidden_node_number_index + hidden_node_number[i] + k]*weight[weight_index + (hidden_node_number[i]+1)*(k) + j + 1]; #ifdef ALPINE_DEBUG elog(WARNING,"i:%d j:%d k:%d; hidden_node_error[%d]:%f,weight[%d]:%f",i,j,k,hidden_node_number_index + hidden_node_number[i] + k, hidden_node_error[hidden_node_number_index + hidden_node_number[i] + k], weight_index + (hidden_node_number[i]+1)*(k) + j + 1,weight[weight_index + (hidden_node_number[i]+1)*(k) + j + 1]); #endif } hidden_node_error[hidden_node_number_index + j] = error_sum*hidden_node_output[hidden_node_number_index + j]*(1-hidden_node_output[hidden_node_number_index + j]); #ifdef ALPINE_DEBUG elog(WARNING,"hidden_node_error[%d] %f ", hidden_node_number_index+j, hidden_node_error[hidden_node_number_index + j]); #endif } weight_index = weight_index - (hidden_node_number[i - 1]+1) * hidden_node_number[i]; hidden_node_number_index = hidden_node_number_index - hidden_node_number[i - 1]; } } //compute weight change of output node weight_index = weight_count - (hidden_node_number[hidden_layer_number_arg - 1]+ 1)* output_node_no_arg; hidden_node_number_index = all_hidden_node_count - hidden_node_number[hidden_layer_number_arg - 1]; for(i = 0; i < output_node_no_arg; i++) { delta = 1.0/set_size_arg*output_error[i]; threshold_change = delta; result_data[weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i)] = Float8GetDatum(threshold_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f ", weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i), threshold_change); #endif for(j = 0; j < hidden_node_number[hidden_layer_number_arg - 1] ; j++) { current_change = delta * hidden_node_output[hidden_node_number_index + j]; result_data[weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i) + 1 +j] = Float8GetDatum(current_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f , i:%d j:%d output_error[%d]:%f, hidden_node_output[%d]:%f", weight_index +(hidden_node_number[hidden_layer_number_arg - 1]+ 1)*(i) + 1+ j, current_change, i,j,i,output_error[i],hidden_node_number_index + j, hidden_node_output[hidden_node_number_index + j]); #endif } } //compute weight change of hidden node last layer to 2 layer if (hidden_layer_number_arg > 1) { for(i = hidden_layer_number_arg - 1; i >= 1; i--) { weight_index = weight_index - (hidden_node_number[i - 1]+1)*hidden_node_number[i]; hidden_node_number_index = hidden_node_number_index - hidden_node_number[i - 1]; delta = 0.0; for (j = 0; j < hidden_node_number[i]; j++) { delta = (1.0/set_size_arg*hidden_node_error[hidden_node_number_index + hidden_node_number[i - 1] + j]); threshold_change = delta; result_data[weight_index + (hidden_node_number[i - 1] + 1) * (j)] = Float8GetDatum(threshold_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f ", weight_index + (hidden_node_number[i - 1] + 1) * (j), threshold_change); #endif for(k = 0; k < hidden_node_number[i - 1]; k++) { current_change = delta * hidden_node_output[hidden_node_number_index + k]; result_data[weight_index + (hidden_node_number[i - 1] + 1) * (j) + 1 + k] = Float8GetDatum(current_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f i:%d, j:%d k:%d hidden_node_error[%d]:%f hidden_node_output[%d]:%f", weight_index + (hidden_node_number[i - 1] + 1) * (j) + 1 + k, current_change,i,j,k,hidden_node_number_index + hidden_node_number[i - 1] + j, hidden_node_error[hidden_node_number_index + hidden_node_number[i - 1] + j], hidden_node_number_index + k,hidden_node_output[hidden_node_number_index + k]); #endif } } } } //compute weight change of first layer hidden node weight_index = 0; hidden_node_number_index = 0; delta = 0.0; for(j = 0; j < hidden_node_number[0]; j++) { delta = 1.0/set_size_arg*hidden_node_error[hidden_node_number_index + j]; threshold_change = delta; result_data[weight_index + (columns_count+1)*(j)] = Float8GetDatum(threshold_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f ", weight_index + (columns_count+1)*(j), threshold_change); #endif for(k = 0; k < columns_count; k++) { current_change = delta*input[k]; result_data[weight_index + (columns_count+1)*(j) + k + 1] = Float8GetDatum(current_change); #ifdef ALPINE_DEBUG elog(WARNING, " result_data [%d] %f j:%d k:%d hidden_node_error[%d]:%f input[%d]:%f", weight_index + (columns_count+1)*(j) + k + 1, current_change,j,k,hidden_node_number_index + j, hidden_node_error[hidden_node_number_index + j], k, input[k]); #endif } } result_data[weight_count] = Float8GetDatum(total_error); ndims = 1; dims = (int *) palloc(sizeof(int)); dims[0] = result_count; lbs = (int *) palloc(sizeof(int)); lbs[0] = 1; result = construct_md_array((void *)result_data, result_nulls, ndims, dims, lbs, result_eltype, result_typlen, result_typbyval, result_typalign); // pfree(result); pfree(weight_data); pfree(columns_data); pfree(input_range_data); pfree(input_base_data); pfree(hidden_node_number_data); pfree(result_data); pfree(weight_nulls); pfree(columns_nulls); pfree(input_range_nulls); pfree(input_base_nulls); pfree(hidden_node_number_nulls); pfree(result_nulls); pfree(input); pfree(output); pfree(lbs); pfree(dims); pfree(hidden_node_output); pfree(weight); pfree(hidden_node_number); pfree(hidden_node_error); pfree(output_error); PG_RETURN_ARRAYTYPE_P(result); }
/* * pivot_accum() - Pivot and accumulate */ static Datum oid_pivot_accum(FunctionCallInfo fcinfo, Oid type) { ArrayType *data; ArrayType *labels; text *attr; int i; /* Simple argument validation */ if (PG_NARGS() != 4) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("pivot_accum called with %d input arguments", PG_NARGS()))); if (PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) { if (PG_ARGISNULL(0)) PG_RETURN_NULL(); PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(0)); } labels = PG_GETARG_ARRAYTYPE_P(1); attr = PG_GETARG_TEXT_P(2); /* Do nothing if the attr isn't in the labels array. */ if ((i = pivot_find(labels, attr)) < 0) { if (PG_ARGISNULL(0)) PG_RETURN_NULL(); PG_RETURN_ARRAYTYPE_P(PG_GETARG_ARRAYTYPE_P(0)); } /* Get the data array, or make it if null */ if (!PG_ARGISNULL(0)) { data = PG_GETARG_ARRAYTYPE_P(0); Assert(ARR_DIMS(labels)[0] == ARR_DIMS(data)[0]); } else { int elsize, size, nelem; switch (type) { case INT4OID: elsize = 4; break; case INT8OID: case FLOAT8OID: elsize = 8; break; default: elsize = 0; /* Fixes complier warnings */ Assert(false); } nelem = ARR_DIMS(labels)[0]; size = nelem * elsize + ARR_OVERHEAD_NONULLS(1); data = (ArrayType *) palloc(size); SET_VARSIZE(data, size); data->ndim = 1; data->dataoffset = 0; data->elemtype = type; ARR_DIMS(data)[0] = nelem; ARR_LBOUND(data)[0] = 1; memset(ARR_DATA_PTR(data), 0, nelem * elsize); } /* * Should we think about upconverting the arrays? Or is the assumption that * the pivot isn't usually doing much aggregation? */ switch (type) { case INT4OID: { int32 *datap = (int32*) ARR_DATA_PTR(data); int32 value = PG_GETARG_INT32(3); datap[i] += value; break; } case INT8OID: { int64 *datap = (int64*) ARR_DATA_PTR(data); int64 value = PG_GETARG_INT64(3); datap[i] += value; break; } case FLOAT8OID: { float8 *datap = (float8*) ARR_DATA_PTR(data); float8 value = PG_GETARG_FLOAT8(3); datap[i] += value; break; } default: Assert(false); } PG_RETURN_ARRAYTYPE_P(data); }
Datum float8arr_cast_float8(PG_FUNCTION_ARGS) { float8 value=PG_GETARG_FLOAT8(0); PG_RETURN_ARRAYTYPE_P(svec_return_array_internal(svec_make_scalar(value,1))); }
Datum alpine_miner_lr_ca_he_de_accum(PG_FUNCTION_ARGS) { ArrayType *beta_arg, *columns_arg, *result; float8 *beta_data, *columns_data, *result_data; int beta_count, columns_count, result_count; int size; bool add_intercept_arg; double weight_arg; int y_arg; double fitness = 0.0; double gx = 0.0; double pi = 0.0; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3) || PG_ARGISNULL(4) || PG_ARGISNULL(5)){ PG_RETURN_NULL(); } result = PG_GETARG_ARRAYTYPE_P(0); beta_arg = PG_GETARG_ARRAYTYPE_P(1); columns_arg = PG_GETARG_ARRAYTYPE_P(2); add_intercept_arg = PG_GETARG_BOOL(3); weight_arg = PG_GETARG_FLOAT8(4); y_arg = PG_GETARG_INT32(5); result_data = (float8*) ARR_DATA_PTR(result); beta_data = (float8*) ARR_DATA_PTR(beta_arg); columns_data = (float8*) ARR_DATA_PTR(columns_arg); result_count = ARR_DIMS(result)[0]; beta_count = ARR_DIMS(beta_arg)[0]; columns_count = ARR_DIMS(columns_arg)[0]; // float8 * column_array_data = (float8*) ARR_DATA_PTR(column_array); if (result_count == 1){ result_count = beta_count *(beta_count+1)/2 + beta_count + 1; size = result_count * sizeof(float8) + ARR_OVERHEAD_NONULLS(1); result = (ArrayType *) palloc(size); SET_VARSIZE(result, size); result->ndim = 1; result->dataoffset = 0; result->elemtype = FLOAT8OID; ARR_DIMS(result)[0] = result_count; ARR_LBOUND(result)[0] = 1; result_data = (float8*) ARR_DATA_PTR(result); memset(result_data, 0, result_count * sizeof(float8)); } pi = alpine_miner_compute_pi(beta_data, beta_count, columns_data, columns_count, add_intercept_arg); alpine_miner_compute_hessian(beta_count,beta_data,columns_data, result_data ,weight_arg, add_intercept_arg, pi); alpine_miner_compute_derivative(columns_count,columns_data, &result_data[beta_count *(beta_count+1)/2] ,weight_arg, y_arg, add_intercept_arg, pi); if (y_arg == 1) { fitness = log(pi); } else { fitness = log(1.0 - pi); } fitness *= weight_arg; result_data[result_count - 1] = fitness + result_data[result_count - 1]; PG_RETURN_ARRAYTYPE_P(result); }
Datum float8arr_cast_numeric(PG_FUNCTION_ARGS) { Datum num=PG_GETARG_DATUM(0); float8 value; value = DatumGetFloat8(DirectFunctionCall1(numeric_float8_no_overflow,num)); PG_RETURN_ARRAYTYPE_P(svec_return_array_internal(svec_make_scalar(value,1))); }
Datum tuple_data_split(PG_FUNCTION_ARGS) { Oid relid; bytea *raw_data; uint16 t_infomask; uint16 t_infomask2; char *t_bits_str; bool do_detoast = false; bits8 *t_bits = NULL; Datum res; relid = PG_GETARG_OID(0); raw_data = PG_ARGISNULL(1) ? NULL : PG_GETARG_BYTEA_P(1); t_infomask = PG_GETARG_INT16(2); t_infomask2 = PG_GETARG_INT16(3); t_bits_str = PG_ARGISNULL(4) ? NULL : text_to_cstring(PG_GETARG_TEXT_PP(4)); if (PG_NARGS() >= 6) do_detoast = PG_GETARG_BOOL(5); if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("must be superuser to use raw page functions"))); if (!raw_data) PG_RETURN_NULL(); /* * Convert t_bits string back to the bits8 array as represented in the * tuple header. */ if (t_infomask & HEAP_HASNULL) { int bits_str_len; int bits_len; bits_len = BITMAPLEN(t_infomask2 & HEAP_NATTS_MASK) * BITS_PER_BYTE; if (!t_bits_str) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("argument of t_bits is null, but it is expected to be null and %d character long", bits_len))); bits_str_len = strlen(t_bits_str); if (bits_len != bits_str_len) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("unexpected length of t_bits %u, expected %d", bits_str_len, bits_len))); /* do the conversion */ t_bits = text_to_bits(t_bits_str, bits_str_len); } else { if (t_bits_str) ereport(ERROR, (errcode(ERRCODE_DATA_CORRUPTED), errmsg("t_bits string is expected to be NULL, but instead it is %zu bytes length", strlen(t_bits_str)))); } /* Split tuple data */ res = tuple_data_split_internal(relid, (char *) raw_data + VARHDRSZ, VARSIZE(raw_data) - VARHDRSZ, t_infomask, t_infomask2, t_bits, do_detoast); if (t_bits) pfree(t_bits); PG_RETURN_ARRAYTYPE_P(res); }
Datum array_multi_index( PG_FUNCTION_ARGS ) { if( PG_ARGISNULL(0) ) { PG_RETURN_NULL(); } if( PG_ARGISNULL(1) ) { PG_RETURN_NULL(); } ArrayType* values = PG_GETARG_ARRAYTYPE_P( 0 ); ArrayType* indices = PG_GETARG_ARRAYTYPE_P( 1 ); Oid values_type = ARR_ELEMTYPE( values ); int16 values_width; bool values_passbyvalue; char values_alignmentcode; Datum* values_content; bool* values_nullflags; int values_length; get_typlenbyvalalign( values_type, &values_width, &values_passbyvalue, &values_alignmentcode ); deconstruct_array( values, values_type, values_width, values_passbyvalue, values_alignmentcode, &values_content, &values_nullflags, &values_length ); Oid indices_type = ARR_ELEMTYPE( indices ); int16 indices_width; bool indices_passbyvalue; char indices_alignmentcode; Datum* indices_content; bool* indices_nullflags; int indices_length; get_typlenbyvalalign( indices_type, &indices_width, &indices_passbyvalue, &indices_alignmentcode ); deconstruct_array( indices, indices_type, indices_width, indices_passbyvalue, indices_alignmentcode, &indices_content, &indices_nullflags, &indices_length ); Oid results_type = values_type; int16 results_width = values_width; bool results_passbyvalue = values_passbyvalue; char results_alignmentcode = values_alignmentcode; Datum* results_content = (Datum *)palloc( sizeof(Datum) * indices_length ); bool* results_nullflags = (bool *)palloc0( sizeof(bool) * indices_length ); int results_length = indices_length; int i; for( i = 0; i < indices_length; ++i ) { if( indices_nullflags[i] ) { results_content[i] = 0; results_nullflags[i] = true; } else if( indices_content[i] - 1 >= (long unsigned)values_length ) { results_content[i] = 0; results_nullflags[i] = true; } else { results_content[i] = values_content[ indices_content[i] - 1 ]; results_nullflags[i] = values_nullflags[ indices_content[i] - 1 ]; } } int dims[1]; int lbs[1]; dims[0] = results_length; lbs[0] = 1; ArrayType* results = construct_md_array( results_content, results_nullflags, 1, dims, lbs, results_type, results_width, results_passbyvalue, results_alignmentcode ); pfree( results_content ); pfree( results_nullflags ); PG_RETURN_ARRAYTYPE_P( results ); }
Datum internal_kmeans_agg_centroid_trans(PG_FUNCTION_ARGS) { ArrayType *array = NULL; ArrayType *cent_array = NULL; int32 dimension; int32 num_of_centroids; int32 centroid_index; bool rebuild_array = false; int32 expected_array_len; float8 *c_array = NULL; cent_array = PG_GETARG_ARRAYTYPE_P(verify_arg_nonnull(fcinfo, 1)); int array_dim = ARR_NDIM(cent_array); int *p_array_dim = ARR_DIMS(cent_array); int array_length = ArrayGetNItems(array_dim, p_array_dim); float8* c_cent_array = (float8 *)ARR_DATA_PTR(cent_array); dimension = PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 2)); num_of_centroids = PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 3)); centroid_index = PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 4)); expected_array_len = num_of_centroids*dimension; if (dimension < 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("function \"%s\", Invalid dimension:%d", format_procedure(fcinfo->flinfo->fn_oid), dimension))); } if (array_length != dimension) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("function \"%s\", Inconsistent Dimension. " "Expected:%d, Actual:%d", format_procedure(fcinfo->flinfo->fn_oid), dimension, array_length))); } if (num_of_centroids < 1) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("function \"%s\", Invalid num_of_centroids:%d", format_procedure(fcinfo->flinfo->fn_oid), num_of_centroids))); } if (centroid_index < 1 || centroid_index>num_of_centroids) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("function \"%s\", Invalid centroid_index:%d", format_procedure(fcinfo->flinfo->fn_oid), centroid_index))); } if (PG_ARGISNULL(0)) { c_array = palloc0(expected_array_len*sizeof(float8)); rebuild_array = true; } else { if (fcinfo->context && IsA(fcinfo->context, AggState)) array = PG_GETARG_ARRAYTYPE_P(0); else array = PG_GETARG_ARRAYTYPE_P_COPY(0); array_dim = ARR_NDIM(array); p_array_dim = ARR_DIMS(array); array_length = ArrayGetNItems(array_dim, p_array_dim); if (array_length != expected_array_len) { ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("function \"%s\", Invalid array length. " "Expected: %d, Actual:%d", format_procedure(fcinfo->flinfo->fn_oid), expected_array_len, array_length))); } c_array = (float8 *)ARR_DATA_PTR(array); } float8 * data_ptr = c_array+(centroid_index-1)*dimension; for(int index=0; index<dimension; index++) { data_ptr[index] = c_cent_array[index]; } if (rebuild_array) { /* construct a new array to keep the aggr states. */ array = construct_array( (Datum *)c_array, expected_array_len, FLOAT8OID, sizeof(float8), true, 'd' ); } PG_RETURN_ARRAYTYPE_P(array); }
/*----------------------------------------------------------------------------- * array_cat : * concatenate two nD arrays to form an nD array, or * push an (n-1)D array onto the end of an nD array *---------------------------------------------------------------------------- */ Datum array_cat(PG_FUNCTION_ARGS) { ArrayType *v1, *v2; int *dims, *lbs, ndims, ndatabytes, nbytes; int *dims1, *lbs1, ndims1, ndatabytes1; int *dims2, *lbs2, ndims2, ndatabytes2; int i; char *dat1, *dat2; Oid element_type; Oid element_type1; Oid element_type2; ArrayType *result; v1 = PG_GETARG_ARRAYTYPE_P(0); v2 = PG_GETARG_ARRAYTYPE_P(1); element_type1 = ARR_ELEMTYPE(v1); element_type2 = ARR_ELEMTYPE(v2); /* Check we have matching element types */ if (element_type1 != element_type2) ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with element types %s and %s are not " "compatible for concatenation.", format_type_be(element_type1), format_type_be(element_type2)))); /* OK, use it */ element_type = element_type1; /*---------- * We must have one of the following combinations of inputs: * 1) one empty array, and one non-empty array * 2) both arrays empty * 3) two arrays with ndims1 == ndims2 * 4) ndims1 == ndims2 - 1 * 5) ndims1 == ndims2 + 1 *---------- */ ndims1 = ARR_NDIM(v1); ndims2 = ARR_NDIM(v2); /* * short circuit - if one input array is empty, and the other is not, we * return the non-empty one as the result * * if both are empty, return the first one */ if (ndims1 == 0 && ndims2 > 0) PG_RETURN_ARRAYTYPE_P(v2); if (ndims2 == 0) PG_RETURN_ARRAYTYPE_P(v1); /* the rest fall under rule 3, 4, or 5 */ if (ndims1 != ndims2 && ndims1 != ndims2 - 1 && ndims1 != ndims2 + 1) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays of %d and %d dimensions are not " "compatible for concatenation.", ndims1, ndims2))); /* get argument array details */ lbs1 = ARR_LBOUND(v1); lbs2 = ARR_LBOUND(v2); dims1 = ARR_DIMS(v1); dims2 = ARR_DIMS(v2); dat1 = ARR_DATA_PTR(v1); dat2 = ARR_DATA_PTR(v2); ndatabytes1 = ARR_SIZE(v1) - ARR_OVERHEAD(ndims1); ndatabytes2 = ARR_SIZE(v2) - ARR_OVERHEAD(ndims2); if (ndims1 == ndims2) { /* * resulting array is made up of the elements (possibly arrays * themselves) of the input argument arrays */ ndims = ndims1; dims = (int *) palloc(ndims * sizeof(int)); lbs = (int *) palloc(ndims * sizeof(int)); dims[0] = dims1[0] + dims2[0]; lbs[0] = lbs1[0]; for (i = 1; i < ndims; i++) { if (dims1[i] != dims2[i] || lbs1[i] != lbs2[i]) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with differing element dimensions are " "not compatible for concatenation."))); dims[i] = dims1[i]; lbs[i] = lbs1[i]; } } else if (ndims1 == ndims2 - 1) { /* * resulting array has the second argument as the outer array, with * the first argument appended to the front of the outer dimension */ ndims = ndims2; dims = (int *) palloc(ndims * sizeof(int)); lbs = (int *) palloc(ndims * sizeof(int)); memcpy(dims, dims2, ndims * sizeof(int)); memcpy(lbs, lbs2, ndims * sizeof(int)); /* increment number of elements in outer array */ dims[0] += 1; /* decrement outer array lower bound */ lbs[0] -= 1; /* make sure the added element matches our existing elements */ for (i = 0; i < ndims1; i++) { if (dims1[i] != dims[i + 1] || lbs1[i] != lbs[i + 1]) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with differing dimensions are not " "compatible for concatenation."))); } } else { /* * (ndims1 == ndims2 + 1) * * resulting array has the first argument as the outer array, with the * second argument appended to the end of the outer dimension */ ndims = ndims1; dims = (int *) palloc(ndims * sizeof(int)); lbs = (int *) palloc(ndims * sizeof(int)); memcpy(dims, dims1, ndims * sizeof(int)); memcpy(lbs, lbs1, ndims * sizeof(int)); /* increment number of elements in outer array */ dims[0] += 1; /* make sure the added element matches our existing elements */ for (i = 0; i < ndims2; i++) { if (dims2[i] != dims[i + 1] || lbs2[i] != lbs[i + 1]) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), errmsg("cannot concatenate incompatible arrays"), errdetail("Arrays with differing dimensions are not " "compatible for concatenation."))); } } /* build the result array */ ndatabytes = ndatabytes1 + ndatabytes2; nbytes = ndatabytes + ARR_OVERHEAD(ndims); result = (ArrayType *) palloc(nbytes); result->size = nbytes; result->ndim = ndims; result->flags = 0; result->elemtype = element_type; memcpy(ARR_DIMS(result), dims, ndims * sizeof(int)); memcpy(ARR_LBOUND(result), lbs, ndims * sizeof(int)); /* data area is arg1 then arg2 */ memcpy(ARR_DATA_PTR(result), dat1, ndatabytes1); memcpy(ARR_DATA_PTR(result) + ndatabytes1, dat2, ndatabytes2); PG_RETURN_ARRAYTYPE_P(result); }
/** * Returns a histogram from an array of numbers. * by Paul A. Jungwirth */ Datum array_to_hist(PG_FUNCTION_ARGS) { // Our arguments: ArrayType *vals; pgnum bucketsStart; pgnum bucketsSize; int32 bucketsCount; // The array element type: Oid valsType; // The array element type widths for our input and output arrays: int16 valsTypeWidth; int16 histTypeWidth; // The array element type "is passed by value" flags (not really used): bool valsTypeByValue; bool histTypeByValue; // The array element type alignment codes (not really used): char valsTypeAlignmentCode; char histTypeAlignmentCode; // The array contents, as PostgreSQL "Datum" objects: Datum *valsContent; Datum *histContent; // List of "is null" flags for the array contents (not used): bool *valsNullFlags; // The size of the input array: int valsLength; // The output array: ArrayType* histArray; pgnum histMax; pgnum v; int i; if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2) || PG_ARGISNULL(3)) { ereport(ERROR, (errmsg("Null arguments not accepted"))); } vals = PG_GETARG_ARRAYTYPE_P(0); if (ARR_NDIM(vals) > 1) { ereport(ERROR, (errmsg("One-dimesional arrays are required"))); } if (array_contains_nulls(vals)) { ereport(ERROR, (errmsg("Array contains null elements"))); } // Determine the array element types. valsType = ARR_ELEMTYPE(vals); if (valsType != INT2OID && valsType != INT4OID && valsType != INT8OID && valsType != FLOAT4OID && valsType != FLOAT8OID) { ereport(ERROR, (errmsg("Histogram subject must be SMALLINT, INTEGER, BIGINT, REAL, or DOUBLE PRECISION values"))); } valsLength = (ARR_DIMS(vals))[0]; switch (valsType) { case INT2OID: bucketsStart.i16 = PG_GETARG_INT16(1); bucketsSize.i16 = PG_GETARG_INT16(2); break; case INT4OID: bucketsStart.i32 = PG_GETARG_INT32(1); bucketsSize.i32 = PG_GETARG_INT32(2); break; case INT8OID: bucketsStart.i64 = PG_GETARG_INT64(1); bucketsSize.i64 = PG_GETARG_INT64(2); break; case FLOAT4OID: bucketsStart.f4 = PG_GETARG_FLOAT4(1); bucketsSize.f4 = PG_GETARG_FLOAT4(2); break; case FLOAT8OID: bucketsStart.f8 = PG_GETARG_FLOAT8(1); bucketsSize.f8 = PG_GETARG_FLOAT8(2); break; default: break; } bucketsCount = PG_GETARG_INT32(3); get_typlenbyvalalign(valsType, &valsTypeWidth, &valsTypeByValue, &valsTypeAlignmentCode); // Extract the array contents (as Datum objects). deconstruct_array(vals, valsType, valsTypeWidth, valsTypeByValue, valsTypeAlignmentCode, &valsContent, &valsNullFlags, &valsLength); // Create a new array of histogram bins (as Datum objects). // Memory we palloc is freed automatically at the end of the transaction. histContent = palloc0(sizeof(Datum) * bucketsCount); // Generate the histogram switch (valsType) { case INT2OID: histMax.i16 = bucketsStart.i16 + (bucketsSize.i16 * bucketsCount); for (i = 0; i < valsLength; i++) { v.i16 = DatumGetInt16(valsContent[i]); if (v.i16 >= bucketsStart.i16 && v.i16 <= histMax.i16) { int b = (v.i16 - bucketsStart.i16) / bucketsSize.i16; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; case INT4OID: histMax.i32 = bucketsStart.i32 + (bucketsSize.i32 * bucketsCount); for (i = 0; i < valsLength; i++) { v.i32 = DatumGetInt32(valsContent[i]); if (v.i32 >= bucketsStart.i32 && v.i32 <= histMax.i32) { int b = (v.i32 - bucketsStart.i32) / bucketsSize.i32; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; case INT8OID: histMax.i64 = bucketsStart.i64 + (bucketsSize.i64 * bucketsCount); for (i = 0; i < valsLength; i++) { v.i64 = DatumGetInt64(valsContent[i]); if (v.i64 >= bucketsStart.i64 && v.i64 <= histMax.i64) { int b = (v.i64 - bucketsStart.i64) / bucketsSize.i64; if (b >= 0 && b < bucketsCount) { histContent[b] = Int64GetDatum(DatumGetInt64(histContent[b]) + 1); } } } break; case FLOAT4OID: histMax.f4 = bucketsStart.f4 + (bucketsSize.f4 * bucketsCount); for (i = 0; i < valsLength; i++) { v.f4 = DatumGetFloat4(valsContent[i]); if (v.f4 >= bucketsStart.f4 && v.f4 <= histMax.f4) { int b = (v.f4 - bucketsStart.f4) / bucketsSize.f4; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; case FLOAT8OID: histMax.f8 = bucketsStart.f8 + (bucketsSize.f8 * bucketsCount); for (i = 0; i < valsLength; i++) { v.f8 = DatumGetFloat8(valsContent[i]); if (v.f8 >= bucketsStart.f8 && v.f8 <= histMax.f8) { int b = (v.f8 - bucketsStart.f8) / bucketsSize.f8; if (b >= 0 && b < bucketsCount) { histContent[b] = Int32GetDatum(DatumGetInt32(histContent[b]) + 1); } } } break; default: break; } // Wrap the buckets in a new PostgreSQL array object. get_typlenbyvalalign(INT4OID, &histTypeWidth, &histTypeByValue, &histTypeAlignmentCode); histArray = construct_array(histContent, bucketsCount, INT4OID, histTypeWidth, histTypeByValue, histTypeAlignmentCode); // Return the final PostgreSQL array object. PG_RETURN_ARRAYTYPE_P(histArray); }
Datum __vcrf_sum_array(PG_FUNCTION_ARGS) { ArrayType *v1, *v2; ArrayType *result; // int *dims, // *lbs, int ndims, // nitems, ndatabytes, nbytes; int nitems1, nitems2; // int *dims1, // *lbs1, // ndims1, // nitems1, // ndatabytes1; // int *dims2, // *lbs2, // ndims2, // nitems2, // ndatabytes2; int i; // char *dat1, // *dat2; // bits8 *bitmap1, // *bitmap2; Oid element_type; // Oid element_type1; // Oid element_type2; int32 dataoffset; int spos; if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) abort(); // pointers to the postgres arrays v1 = PG_GETARG_ARRAYTYPE_P(0); v2 = PG_GETARG_ARRAYTYPE_P(1); // postgres type of elements in an array element_type = ARR_ELEMTYPE(v1); // number of items in the arrays nitems1 = ARR_DIMS(v1)[0]; nitems2 = ARR_DIMS(v2)[0]; // if (nitems1 == 0 || nitems2 == 0 || nitems2 % nitems1 != 0) // abort(); /* new array is the same as v1 for top 1 only !! */ ndims = ARR_NDIM(v1); ndatabytes = ARR_SIZE(v1) - ARR_DATA_OFFSET(v1); dataoffset = 0; /* marker for no null bitmap */ nbytes = ndatabytes + ARR_OVERHEAD_NONULLS(ndims); result = (ArrayType *) palloc(nbytes); SET_VARSIZE(result, nbytes); result->ndim = ndims; result->dataoffset = dataoffset; result->elemtype = element_type; for(i=0;i<ndims;i++) { ARR_DIMS(result)[i]=ARR_DIMS(v1)[i]; ARR_LBOUND(result)[i]=ARR_LBOUND(v1)[i]; } // array v2 can either have nitems1 or nitems1*nitems1 or (nitems1+1)*nitems1 items, because of the -1 arrays from MR // for the first and third case we want to skip the first nitems1 items //int spos=0; spos = nitems2 % (nitems1*nitems1); for(i=0; i<nitems1; i++) ((int*)ARR_DATA_PTR(result))[i] = 0; // do sum over all possible value of y' calculation here for(i = spos; i < nitems2; i++) { int k = (i-spos) / nitems1; int k_rem = i % nitems1; int new_score = ((int*)ARR_DATA_PTR(v1))[0*nitems1+k] + ((int*)ARR_DATA_PTR(v2))[i]; // 0.5 is for rounding ((int*)ARR_DATA_PTR(result))[0*nitems1+k_rem] = (int)(log(exp(((int*)ARR_DATA_PTR(result))[0*nitems1+k_rem]/1000.0) + exp(new_score/1000.0))*1000.0 + 0.5); } PG_RETURN_ARRAYTYPE_P(result); }
/*----------------------------------------------------------------------------- * array_push : * push an element onto either end of a one-dimensional array *---------------------------------------------------------------------------- */ Datum array_push(PG_FUNCTION_ARGS) { ArrayType *v; Datum newelem; bool isNull; int *dimv, *lb; ArrayType *result; int indx; Oid element_type; int16 typlen; bool typbyval; char typalign; Oid arg0_typeid = get_fn_expr_argtype(fcinfo->flinfo, 0); Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1); Oid arg0_elemid; Oid arg1_elemid; ArrayMetaState *my_extra; if (arg0_typeid == InvalidOid || arg1_typeid == InvalidOid) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not determine input data types"))); arg0_elemid = get_element_type(arg0_typeid); arg1_elemid = get_element_type(arg1_typeid); if (arg0_elemid != InvalidOid) { if (PG_ARGISNULL(0)) v = construct_empty_array(arg0_elemid); else v = PG_GETARG_ARRAYTYPE_P(0); isNull = PG_ARGISNULL(1); if (isNull) newelem = (Datum) 0; else newelem = PG_GETARG_DATUM(1); } else if (arg1_elemid != InvalidOid) { if (PG_ARGISNULL(1)) v = construct_empty_array(arg1_elemid); else v = PG_GETARG_ARRAYTYPE_P(1); isNull = PG_ARGISNULL(0); if (isNull) newelem = (Datum) 0; else newelem = PG_GETARG_DATUM(0); } else { /* Shouldn't get here given proper type checking in parser */ ereport(ERROR, (errcode(ERRCODE_DATATYPE_MISMATCH), errmsg("neither input type is an array"))); PG_RETURN_NULL(); /* keep compiler quiet */ } element_type = ARR_ELEMTYPE(v); if (ARR_NDIM(v) == 1) { lb = ARR_LBOUND(v); dimv = ARR_DIMS(v); if (arg0_elemid != InvalidOid) { /* append newelem */ int ub = dimv[0] + lb[0] - 1; indx = ub + 1; /* overflow? */ if (indx < ub) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } else { /* prepend newelem */ indx = lb[0] - 1; /* overflow? */ if (indx > lb[0]) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), errmsg("integer out of range"))); } } else if (ARR_NDIM(v) == 0) indx = 1; else ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), errmsg("argument must be empty or one-dimensional array"))); /* * We arrange to look up info about element type only once per series of * calls, assuming the element type doesn't change underneath us. */ my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; if (my_extra == NULL) { fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt, sizeof(ArrayMetaState)); my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra; my_extra->element_type = ~element_type; } if (my_extra->element_type != element_type) { /* Get info about element type */ get_typlenbyvalalign(element_type, &my_extra->typlen, &my_extra->typbyval, &my_extra->typalign); my_extra->element_type = element_type; } typlen = my_extra->typlen; typbyval = my_extra->typbyval; typalign = my_extra->typalign; result = array_set(v, 1, &indx, newelem, isNull, -1, typlen, typbyval, typalign); /* * Readjust result's LB to match the input's. This does nothing in the * append case, but it's the simplest way to implement the prepend case. */ if (ARR_NDIM(v) == 1) ARR_LBOUND(result)[0] = ARR_LBOUND(v)[0]; PG_RETURN_ARRAYTYPE_P(result); }
Datum __vcrf_max_top1_array(PG_FUNCTION_ARGS) { ArrayType *v1 ; // , // *v2; ArrayType *result; // int *dims, // *lbs, int ndims, // nitems, ndatabytes, nbytes; int nitems1; // int *dims1, // *lbs1, // ndims1, // nitems1, // ndatabytes1; // int *dims2, // *lbs2, // ndims2, // nitems2, // ndatabytes2; int i; // char *dat1, // *dat2; // bits8 *bitmap1, // *bitmap2; Oid element_type; // Oid element_type1; // Oid element_type2; int32 dataoffset; if (PG_ARGISNULL(0)) abort(); v1 = PG_GETARG_ARRAYTYPE_P(0); element_type = ARR_ELEMTYPE(v1); nitems1 = ARR_DIMS(v1)[1]; if (nitems1 == 0) abort(); /* new array is the same as v1 for top 1 only !! */ ndims = 2; ndatabytes = 3*sizeof(int); dataoffset = 0; /* marker for no null bitmap */ nbytes = ndatabytes + ARR_OVERHEAD_NONULLS(ndims); result = (ArrayType *) palloc(nbytes); SET_VARSIZE(result, nbytes); result->ndim = ndims; result->dataoffset = dataoffset; result->elemtype = element_type; ARR_DIMS(result)[0]=3; /* num elements in first dim */ ARR_DIMS(result)[1]=1; /* num elements in second dim */ /* postgres arrays can be index from any start position eg: * int[-5:14]. this is unlike c, where index always starts at 0 */ ARR_LBOUND(result)[0]=1; /* index of the first dim starts at .. */ ARR_LBOUND(result)[1]=1; /* index of second dim starts at ... */ // do top1 calculation here for(i = 0; i < nitems1; i++) { if (i == 0 || ((int*)ARR_DATA_PTR(v1))[0*nitems1+i] > ((int*)ARR_DATA_PTR(v1))[0*nitems1+((int*)ARR_DATA_PTR(result))[0*1+0]]) { ((int*)ARR_DATA_PTR(result))[0*1+0] = i; ((int*)ARR_DATA_PTR(result))[1*1+0] = ((int*)ARR_DATA_PTR(v1))[1*nitems1+i]; ((int*)ARR_DATA_PTR(result))[2*1+0] = ((int*)ARR_DATA_PTR(v1))[0*nitems1+i]; } } PG_RETURN_ARRAYTYPE_P(result); }