/*
 * Calculates the values of all the estimated functions at the breakpoints.
 * The function values will be calculated at the start and end of each
 * subinterval, which is marked by the breakpoints.
 */
double* get_func_vals_at_breakpoints(est_data** pieces, int num_breakpoints)
{
    int i, j;
    double* func_eval = malloc(num_breakpoints * 2 * sizeof(double));
        
    for (i = 0, j = 0; i < num_breakpoints + 1; ++i, j += 2) {
	if (pieces[i] == NULL)
	    break;
	
	/* printf("%lf, %lf, %lf, %lf\n", pieces[i]->est_a, pieces[i]->est_b, pieces[i]->start, pieces[i]->end); */
	/* printf("function at interval start (%lf): %lf\n ", pieces[i]->start, evaluate_function(pieces[i]->est_a, pieces[i]->est_b, pieces[i]->start)); */
	/* printf("function at interval end (%lf) %lf\n", pieces[i]->end, evaluate_function(pieces[i]->est_a, pieces[i]->est_b, pieces[i]->end)); */
	func_eval[j] = evaluate_function(pieces[i]->est_a, pieces[i]->est_b, pieces[i]->start);
	func_eval[j+1] = evaluate_function(pieces[i]->est_a, pieces[i]->est_b, pieces[i]->end);
    }

    return func_eval;
}
void evaluate(double * polynomial, int degree, double * inputlist, int num_inputs, double (evaluate_function)(double *, int, double)) {
	int i;
	printf("p(x) = ");
	print_polynomial(polynomial, degree);
	printf("\n");
	for (i = 0; i < num_inputs; i++) {
		double input = inputlist[i];
		double output = evaluate_function(polynomial, degree, input);
		printf("p(%.1lf) = %lf\n", input, output);
	}
}
示例#3
0
svalue_t evaluate_expression(int start, int stop)
{
	int i, n;
	
	if(killscript) return nullvar;  // killing the script
	
	// possible pointless brackets
	if(tokentype[start] == operator_ && tokentype[stop] == operator_)
		pointless_brackets(&start, &stop);
	
	if(start == stop)       // only 1 thing to evaluate
    {
		return simple_evaluate(start);
    }
	
	// go through each operator in order of precedence
	
	for(i=0; i<num_operators; i++)
    {
		// check backwards for the token. it has to be
		// done backwards for left-to-right reading: eg so
		// 5-3-2 is (5-3)-2 not 5-(3-2)
		
		if( -1 != (n = (operators[i].direction==forward ?
						find_operator_backwards : find_operator)
						  (start, stop, operators[i].string)) )
		{
			// C_Printf("operator %s, %i-%i-%i\n", operators[count].string, start, n, stop);
			
			// call the operator function and evaluate this chunk of tokens
			
			return operators[i].handler(start, n, stop);
		}
    }
	
	if(tokentype[start] == function)
		return evaluate_function(start, stop);
	
	// error ?
	{        
		char tempstr[1024]="";
		
		for(i=start; i<=stop; i++)
			sprintf(tempstr,"%s %s", tempstr, tokens[i]);
		script_error("couldnt evaluate expression: %s\n",tempstr);
		return nullvar;
	}
	
}
示例#4
0
Value Parser::evaluate_instruction(unsigned char* iBlock, unsigned int iSize, unsigned int& tLoc) {
    tick();

    // Conditional
    if (mGrammar->isConditional(iBlock[tLoc])) {
        evaluate_conditional(iBlock, iSize, tLoc);
        return Value();
    }

    // Function
    else if (mGrammar->isFunction(iBlock[tLoc]))
        return evaluate_function(iBlock, iSize, tLoc);

    // Data
    else if (mGrammar->isData(iBlock[tLoc]))
        return evaluate_data(iBlock, iSize, tLoc);

    return Value();
}
示例#5
0
static void evaluate(expression * e)
{
    switch (e->type) {
    case expr_type_constant:
	evaluate_constant(e);
	break;
    case expr_type_variable:
	evaluate_variable(e);
	break;
    case expr_type_map:
	evaluate_map(e);
	break;
    case expr_type_function:
	evaluate_function(e);
	break;
    case expr_type_binding:
	evaluate_binding(e);
	break;
    default:
	G_fatal_error(_("Unknown type: %d"), e->type);
    }
}
示例#6
0
文件: df1b2lp6.cpp 项目: pwoo/admb
/**
 * Description not yet available.
 * \param
 */
void laplace_approximation_calculator::
  do_newton_raphson_banded(function_minimizer * pfmin,double f_from_1,
  int& no_converge_flag)
{
  //quadratic_prior * tmpptr=quadratic_prior::ptr[0];
  //cout << tmpptr << endl;


  laplace_approximation_calculator::where_are_we_flag=2;
  double maxg=fabs(evaluate_function(uhat,pfmin));


  laplace_approximation_calculator::where_are_we_flag=0;
  dvector uhat_old(1,usize);
  for(int ii=1;ii<=num_nr_iters;ii++)
  {
    // test newton raphson
    switch(hesstype)
    {
    case 3:
      bHess->initialize();
      break;
    case 4:
      Hess.initialize();
      break;
    default:
      cerr << "Illegal value for hesstype here" << endl;
      ad_exit(1);
    }

    grad.initialize();
    //int check=initial_params::stddev_scale(scale,uhat);
    //check=initial_params::stddev_curvscale(curv,uhat);
    //max_separable_g=0.0;
    sparse_count = 0;

    step=get_newton_raphson_info_banded(pfmin);
    //if (bHess)
     // cout << "norm(*bHess) = " << norm(*bHess) << endl;
    //cout << "norm(Hess) = " << norm(Hess) << endl;
    //cout << grad << endl;
    //check_pool_depths();
    if (!initial_params::mc_phase)
      cout << "Newton raphson " << ii << "  ";
    if (quadratic_prior::get_num_quadratic_prior()>0)
    {
      quadratic_prior::get_cHessian_contribution(Hess,xsize);
      quadratic_prior::get_cgradient_contribution(grad,xsize);
    }

    int ierr=0;
    if (hesstype==3)
    {
      if (use_dd_nr==0)
      {
        banded_lower_triangular_dmatrix bltd=choleski_decomp(*bHess,ierr);
        if (ierr && no_converge_flag ==0)
        {
          no_converge_flag=1;
          //break;
        }
        if (ierr)
        {
          double oldval;
          evaluate_function(oldval,uhat,pfmin);
          uhat=banded_calculations_trust_region_approach(uhat,pfmin);
        }
        else
        {
          if (dd_nr_flag==0)
          {
            dvector v=solve(bltd,grad);
            step=-solve_trans(bltd,v);
            //uhat_old=uhat;
            uhat+=step;
          }
          else
          {
#if defined(USE_DD_STUFF)
            int n=grad.indexmax();
            maxg=fabs(evaluate_function(uhat,pfmin));
            uhat=dd_newton_raphson2(grad,*bHess,uhat);
#else
            cerr << "high precision Newton Raphson not implemented" << endl;
            ad_exit(1);
#endif
          }
          maxg=fabs(evaluate_function(uhat,pfmin));
          if (f_from_1< pfmin->lapprox->fmc1.fbest)
          {
            uhat=banded_calculations_trust_region_approach(uhat,pfmin);
            maxg=fabs(evaluate_function(uhat,pfmin));
          }
        }
      }
      else
      {
        cout << "error not used" << endl;
        ad_exit(1);
       /*
        banded_symmetric_ddmatrix bHessdd=banded_symmetric_ddmatrix(*bHess);
        ddvector gradd=ddvector(grad);
        //banded_lower_triangular_ddmatrix bltdd=choleski_decomp(bHessdd,ierr);
        if (ierr && no_converge_flag ==0)
        {
          no_converge_flag=1;
          break;
        }
        if (ierr)
        {
          double oldval;
          evaluate_function(oldval,uhat,pfmin);
          uhat=banded_calculations_trust_region_approach(uhat,pfmin);
          maxg=fabs(evaluate_function(uhat,pfmin));
        }
        else
        {
          ddvector v=solve(bHessdd,gradd);
          step=-make_dvector(v);
          //uhat_old=uhat;
          uhat=make_dvector(ddvector(uhat)+step);
          maxg=fabs(evaluate_function(uhat,pfmin));
          if (f_from_1< pfmin->lapprox->fmc1.fbest)
          {
            uhat=banded_calculations_trust_region_approach(uhat,pfmin);
            maxg=fabs(evaluate_function(uhat,pfmin));
          }
        }
        */
      }

      if (maxg < 1.e-13)
      {
        break;
      }
    }
    else if (hesstype==4)
    {
      dvector step;

#     if defined(USE_ATLAS)
        if (!ad_comm::no_atlas_flag)
        {
          step=-atlas_solve_spd(Hess,grad,ierr);
        }
        else
        {
          dmatrix A=choleski_decomp_positive(Hess,ierr);
          if (!ierr)
          {
            step=-solve(Hess,grad);
            //step=-solve(A*trans(A),grad);
          }
        }
        if (!ierr) break;
#     else
        if (sparse_hessian_flag)
        {
          //step=-solve(*sparse_triplet,Hess,grad,*sparse_symbolic);
          dvector temp=solve(*sparse_triplet2,grad,*sparse_symbolic2,ierr);
          if (ierr)
          {
            step=-temp;
          }
          else
          {
            cerr << "matrix not pos definite in sparse choleski"  << endl;
            pfmin->bad_step_flag=1;

            int on;
            int nopt;
            if ((on=option_match(ad_comm::argc,ad_comm::argv,"-ieigvec",nopt))
              >-1)
            {
              dmatrix M=make_dmatrix(*sparse_triplet2);

              ofstream ofs3("inner-eigvectors");
              ofs3 << "eigenvalues and eigenvectors " << endl;
              dvector v=eigenvalues(M);
              dmatrix ev=trans(eigenvectors(M));
              ofs3 << "eigenvectors" << endl;
              int i;
              for (i=1;i<=ev.indexmax();i++)
               {
                  ofs3 << setw(4) << i  << " "
                   << setshowpoint() << setw(14) << setprecision(10) << v(i)
                   << " "
                   << setshowpoint() << setw(14) << setprecision(10)
                   << ev(i) << endl;
               }
            }
          }
          //cout << norm2(step-tmpstep) << endl;
          //dvector step1=-solve(Hess,grad);
          //cout << norm2(step-step1) << endl;
        }
        else
        {
          step=-solve(Hess,grad);
        }
#     endif
      if (pmin->bad_step_flag)
        break;
      uhat_old=uhat;
      uhat+=step;

      double maxg_old=maxg;
      maxg=fabs(evaluate_function(uhat,pfmin));
      if (maxg>maxg_old)
      {
        uhat=uhat_old;
        evaluate_function(uhat,pfmin);
        break;
      }
      if (maxg < 1.e-13)
      {
        break;
      }
    }

    if (sparse_hessian_flag==0)
    {
      for (int i=1;i<=usize;i++)
      {
        y(i+xsize)=uhat(i);
      }
    }
    else
    {
      for (int i=1;i<=usize;i++)
      {
        value(y(i+xsize))=uhat(i);
      }
    }
  }
}
示例#7
0
static int	calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp, char *error, int max_error_len)
{
	const char	*__function_name = "calcitem_evaluate_expression";
	function_t	*f = NULL;
	char		*buf, replace[16], *errstr = NULL;
	int		i, ret = SUCCEED;
	time_t		now;
	zbx_host_key_t	*keys = NULL;
	DC_ITEM		*items = NULL;
	int		*errcodes = NULL;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s()", __function_name);

	if (0 == exp->functions_num)
		return ret;

	keys = zbx_malloc(keys, sizeof(zbx_host_key_t) * exp->functions_num);
	items = zbx_malloc(items, sizeof(DC_ITEM) * exp->functions_num);
	errcodes = zbx_malloc(errcodes, sizeof(int) * exp->functions_num);

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];

		buf = get_param_dyn(f->params, 1);	/* for first parameter result is not NULL */

		if (SUCCEED != parse_host_key(buf, &f->host, &f->key))
		{
			zbx_snprintf(error, max_error_len,
					"Invalid first parameter in function [%s(%s)].",
					f->func, f->params);
			ret = NOTSUPPORTED;
		}

		zbx_free(buf);

		if (SUCCEED != ret)
			goto out;

		if (NULL == f->host)
			f->host = strdup(dc_item->host.host);

		keys[i].host = f->host;
		keys[i].key = f->key;

		remove_param(f->params, 1);

		zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'",
				__function_name, f->host, f->key, f->func, f->params);
	}

	DCconfig_get_items_by_keys(items, keys, errcodes, exp->functions_num);

	now = time(NULL);

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];

		if (SUCCEED != errcodes[i])
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\":"
					" item \"%s:%s\" does not exist.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		if (ITEM_STATUS_ACTIVE != items[i].status)
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\":"
					" item \"%s:%s\" is disabled.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		if (HOST_STATUS_MONITORED != items[i].host.status)
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\":"
					" item \"%s:%s\" belongs to a disabled host.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		if (ITEM_STATE_NOTSUPPORTED == items[i].state)
		{
			zbx_snprintf(error, max_error_len,
					"Cannot evaluate function \"%s(%s)\": item \"%s:%s\" not supported.",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		f->value = zbx_malloc(f->value, MAX_BUFFER_LEN);

		if (SUCCEED != evaluate_function(f->value, &items[i], f->func, f->params, now, &errstr))
		{
			if (NULL != errstr)
			{
				zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\": %s.",
						f->func, f->params, errstr);
				zbx_free(errstr);
			}
			else
			{
				zbx_snprintf(error, max_error_len, "Cannot evaluate function \"%s(%s)\".",
						f->func, f->params);
			}

			ret = NOTSUPPORTED;
			break;
		}

		if (SUCCEED != is_double_suffix(f->value) || '-' == *f->value)
		{
			char	*wrapped;

			wrapped = zbx_dsprintf(NULL, "(%s)", f->value);

			zbx_free(f->value);
			f->value = wrapped;
		}
		else
			f->value = zbx_realloc(f->value, strlen(f->value) + 1);

		zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid);
		buf = string_replace(exp->exp, replace, f->value);
		zbx_free(exp->exp);
		exp->exp = buf;
	}

	DCconfig_clean_items(items, errcodes, exp->functions_num);
out:
	zbx_free(errcodes);
	zbx_free(items);
	zbx_free(keys);

	return ret;
}
示例#8
0
static int	calcitem_evaluate_expression(DC_ITEM *dc_item, expression_t *exp,
		char *error, int max_error_len)
{
	const char	*__function_name = "calcitem_evaluate_expression";
	function_t	*f = NULL;
	char		*sql = NULL, *host_esc, *key_esc,
			*buf, replace[16];
	int		sql_alloc = 1024, sql_offset = 0,
			i, ret = SUCCEED;
	time_t		now;
	DB_RESULT	db_result;
	DB_ROW		db_row;
	DB_ITEM		item;

	zabbix_log(LOG_LEVEL_DEBUG, "In %s() expression:'%s'", __function_name, exp->exp);

	if (0 == exp->functions_num)
		return ret;

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];
		
		buf = get_param_dyn(f->params, 1);	/* for first parameter result is not NULL */

		if (SUCCEED != parse_host_key(buf, &f->host, &f->key))
		{
			zbx_snprintf(error, max_error_len,
					"Invalid first parameter in function [%s(%s)]",
					f->func, f->params);
			ret = NOTSUPPORTED;
		}

		zbx_free(buf);

		if (SUCCEED != ret)
			break;

		if (NULL == f->host)
			f->host = strdup(dc_item->host.host);

		remove_param(f->params, 1);

		zabbix_log(LOG_LEVEL_DEBUG, "%s() function:'%s:%s.%s(%s)'",
				__function_name, f->host, f->key, f->func, f->params);
	}

	if (SUCCEED != ret)
		return ret;

	now = time(NULL);
	sql = zbx_malloc(sql, sql_alloc);

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 512,
			"select %s"
			" where h.hostid=i.hostid"
				" and h.status=%d"
				" and i.status=%d"
				" and (",
			ZBX_SQL_ITEM_SELECT,
			HOST_STATUS_MONITORED,
			ITEM_STATUS_ACTIVE);

	for (i = 0; i < exp->functions_num; i++)
	{
		f = &exp->functions[i];

		if (i != 0)
			zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 8, " or ");

		host_esc = DBdyn_escape_string(f->host);
		key_esc = DBdyn_escape_string(f->key);

		zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset,
				32 + strlen(host_esc) + strlen(key_esc),
				"(h.host='%s' and i.key_='%s')",
				host_esc, key_esc);

		zbx_free(key_esc);
		zbx_free(host_esc);
	}

	zbx_snprintf_alloc(&sql, &sql_alloc, &sql_offset, 130,
			")" DB_NODE,
			DBnode_local("h.hostid"));

	db_result = DBselect("%s", sql);

	zbx_free(sql);

	while (NULL != (db_row = DBfetch(db_result)))
	{
		DBget_item_from_db(&item, db_row);

		for (i = 0; i < exp->functions_num; i++)
		{
			f = &exp->functions[i];

			if (0 != strcmp(f->key, item.key_orig))
				continue;
					
			if (0 != strcmp(f->host, item.host_name))
				continue;

			f->found = 1;
			f->value = zbx_malloc(f->value, MAX_BUFFER_LEN);

			if (SUCCEED != evaluate_function(f->value, &item, f->func, f->params, now))
			{
				zbx_snprintf(error, max_error_len, "Cannot evaluate function [%s(%s)]",
						f->func, f->params);

				ret = NOTSUPPORTED;
				break;
			}
			else
				f->value = zbx_realloc(f->value, strlen(f->value) + 1);
		}

		if (SUCCEED != ret)
			break;
	}
	DBfree_result(db_result);

	if (SUCCEED != ret)
		return ret;

	for (i = 0; i < exp->functions_num; i ++)
	{
		f = &exp->functions[i];

		if (0 == f->found)
		{
			zbx_snprintf(error, max_error_len,
				"Cannot evaluate function [%s(%s)]"
					": item [%s:%s] not found",
					f->func, f->params, f->host, f->key);
			ret = NOTSUPPORTED;
			break;
		}

		zbx_snprintf(replace, sizeof(replace), "{%d}", f->functionid);
		buf = string_replace(exp->exp, replace, f->value);
		zbx_free(exp->exp);
		exp->exp = buf;
	}

	return ret;
}
Number shunting_yard(std::vector<std::string> & tokens, std::vector<std::string> & out_ops, bool boolean_exp = false) {
    prepare();
    std::string previous_token;
    Operator * op;
    Operator * previous_op = new Sum();
    std::string last_token = "";
    std::string token;

    for(auto s = tokens.begin(); s != tokens.end(); ++s) {
        token = *s;
        //std::cout<<token<<std::endl;
        if(is_number(token)) {
            if(is_number(previous_token)) {
                throw std::string("Too many operands");
            }
            if(previous_op && previous_op->sign() == ")") {
                throw std::string("Missing operation between paretheses");
            }
            Number i = parse_number(token);
            if(i >= Number("10", "99") || i <= Number("-10", "99")) {
                //std::cout<<i<<'\n';
                throw std::string("Number out of valid range");
            }

            if(is_variable(token)) {
                std::stringstream g;
                g << i;
                out_ops.push_back(token + "= " + g.str());
            }
            output_stack.push(i);
            previous_op = nullptr;
        }
        else if((op = get_function_op(token)) != nullptr) {
            operator_stack.push(op);
        }

        else if (token == ",") {
            while(!operator_stack.empty() && operator_stack.top()->sign() != "(") {
                evaluate(operator_stack.top(), out_ops);
                operator_stack.pop();
            }
            // error
            if(operator_stack.empty()) {
                throw std::string("mismatched parens");
            }
            // dirty fix, the problem is that in get_operator we only return a
            // negative if there was an operator before, so root(3, -27) was being
            // treated as a substraction
            previous_op = new Sum();
        }

        else if((op = get_operator(token, previous_op, boolean_exp)) != nullptr) {
            if(op->sign() == "(") {
                if(!previous_op || (previous_op && previous_op->sign() == ")" )) {
                    throw std::string("Missing operation between paretheses");
                }
                operator_stack.push(op);
            } else if(op->sign() == ")") {
                while(!operator_stack.empty() && operator_stack.top()->sign() != "(") {
                    evaluate(operator_stack.top(), out_ops);
                    operator_stack.pop();
                }
                // error
                if(operator_stack.empty()) {
                    throw std::string("mismatched parens");
                }
                operator_stack.pop();
                if(!operator_stack.empty() && operator_stack.top()->sign() == "r") {
                    evaluate_function(operator_stack.top(), out_ops);
                    operator_stack.pop();
                }
            }
            else {
                while(!operator_stack.empty() &&
                        ( (op->associativity() == assoc::LEFT && op->precedence() <= operator_stack.top()->precedence())
                          ||
                          (op->associativity() == assoc::RIGHT && op->precedence() < operator_stack.top()->precedence())))
                {
                    evaluate(operator_stack.top(), out_ops);
                    operator_stack.pop();
                }
                operator_stack.push(op);
            }
            previous_op = op;
        }

        else if(token == "=" && !boolean_exp) {
            if(s+1 != tokens.end())
                last_token = *(s+1);
            break;
        }
        // unknown token
        else {
            throw std::string("Unexpected Token '" + token + "'");
        }
        previous_token = token;
    }

    while(!operator_stack.empty()) {
        op = operator_stack.top();
        if(op->sign() == "(") {
            throw std::string("mismatched parens");
        }
        operator_stack.pop();
        evaluate(op, out_ops);
    }

    if(token != "=" && !boolean_exp) {
        throw std::string("Missing =");
    }

    if(!last_token.empty() && !boolean_exp) {
        if(var_map.find(last_token) != var_map.end()) {
            var_map[last_token] = output_stack.top();
            if(tokens[tokens.size()-1] != last_token) {
                throw std::string("Warning, no more expressions after variable assignment");
            }
            // out ops A=
            std::stringstream ss;
            ss << output_stack.top();
            out_ops.push_back(last_token + "= " + ss.str());
            //std::cout << var_map[last_token] << '\n';
        }
        else {
            throw std::string("Warning, no more expressions after =");
        }

    }
    if(output_stack.empty()) return Number ("0","0");

    Number ans = output_stack.top();
    output_stack.pop();
    if(!output_stack.empty()) throw std::string("too many arguments to function");
    return ans;

}
示例#10
0
/******************************************************************************
 *                                                                            *
 * Function: update_functions                                                 *
 *                                                                            *
 * Purpose: re-calculate and updates values of functions related to the item  *
 *                                                                            *
 * Parameters: item - item to update functions for                            *
 *                                                                            *
 * Return value:                                                              *
 *                                                                            *
 * Author: Alexei Vladishev                                                   *
 *                                                                            *
 * Comments:                                                                  *
 *                                                                            *
 ******************************************************************************/
void	update_functions(DB_ITEM *item, time_t now)
{
	DB_FUNCTION	function;
	DB_RESULT	result;
	DB_ROW		row;
	char		value[MAX_STRING_LEN];
	char		*value_esc, *function_esc, *parameter_esc;
	char		*lastvalue;
	int		ret=SUCCEED;

	zabbix_log( LOG_LEVEL_DEBUG, "In update_functions(" ZBX_FS_UI64 ")",
		item->itemid);

/* Oracle does'n support this */
/*	zbx_snprintf(sql,sizeof(sql),"select function,parameter,itemid,lastvalue from functions where itemid=%d group by function,parameter,itemid order by function,parameter,itemid",item->itemid);*/
	result = DBselect("select distinct function,parameter,itemid,lastvalue from functions where itemid=" ZBX_FS_UI64,
		item->itemid);

	while((row=DBfetch(result)))
	{
		function.function=row[0];
		function.parameter=row[1];
		ZBX_STR2UINT64(function.itemid,row[2]);
/*		function.itemid=atoi(row[2]); */
/*		It is not required to check lastvalue for NULL here */
		lastvalue=row[3];

		zabbix_log( LOG_LEVEL_DEBUG, "ItemId:" ZBX_FS_UI64 " Evaluating %s(%s)",
			function.itemid,
			function.function,
			function.parameter);

		ret = evaluate_function(value, item, function.function, function.parameter, now);
		if( FAIL == ret)	
		{
			zabbix_log( LOG_LEVEL_DEBUG, "Evaluation failed for function:%s",
				function.function);
			continue;
		}
		if (ret == SUCCEED)
		{
			/* Update only if lastvalue differs from new one */
			if (DBis_null(lastvalue) == SUCCEED || 0 != strcmp(lastvalue, value))
			{
				value_esc = DBdyn_escape_string_len(value, FUNCTION_LASTVALUE_LEN);
				function_esc = DBdyn_escape_string(function.function);
				parameter_esc = DBdyn_escape_string(function.parameter);

				DBexecute("update functions set lastvalue='%s' where itemid=" ZBX_FS_UI64 " and function='%s' and parameter='%s'",
						value_esc,
						function.itemid,
						function_esc,
						parameter_esc);

				zbx_free(parameter_esc);
				zbx_free(function_esc);
				zbx_free(value_esc);
			}
			else
				zabbix_log( LOG_LEVEL_DEBUG, "Do not update functions, same value");
		}
	}

	DBfree_result(result);

	zabbix_log( LOG_LEVEL_DEBUG, "End update_functions()");
}