예제 #1
0
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);
}
예제 #2
0
파일: regexp.c 프로젝트: winlibs/postgresql
/*
 * 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));
}
예제 #3
0
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);
}
예제 #4
0
/*-----------------------------------------------------------------------------
 * 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);
}
예제 #5
0
/**
 *  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);
}
예제 #6
0
파일: table_group.c 프로젝트: kikht/hvault
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);
}
예제 #7
0
파일: mfvsketch.c 프로젝트: 0x0all/madlib
/*!
 * 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);
}
예제 #8
0
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);
}
예제 #9
0
파일: operators.c 프로젝트: 50wu/gpdb
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)));
}
예제 #10
0
파일: pinv.c 프로젝트: qiuyesuifeng/gpdb
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);
}
예제 #11
0
파일: kissfft.c 프로젝트: pme/pgfft
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);
}
예제 #12
0
파일: regress.c 프로젝트: BenjaminYu/gpdb
/*
 * 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);
}
예제 #13
0
/*
 * 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);
    }

}
예제 #14
0
/*
 * 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);
}
예제 #15
0
/*-----------------------------------------------------------------------------
 * 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);
}
예제 #16
0
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);
}
예제 #17
0
/*
 * 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);
}
예제 #18
0
파일: operators.c 프로젝트: 50wu/gpdb
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)));
}
예제 #19
0
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);
}
예제 #20
0
파일: operators.c 프로젝트: 50wu/gpdb
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)));
}
예제 #21
0
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 ); 
}
예제 #23
0
파일: kmeans.c 프로젝트: 0x0all/madlib
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);
}
예제 #24
0
/*-----------------------------------------------------------------------------
 * 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);
}
예제 #25
0
/**
 * 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);
}
예제 #26
0
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);
}
예제 #27
0
/*-----------------------------------------------------------------------------
 * 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);
}
예제 #28
0
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);
}