Logo Search packages:      
Sourcecode: nco version File versions  Download package

nco_rth_utl.c

/* $Header: /cvsroot/nco/nco/src/nco/nco_rth_utl.c,v 1.18 2004/09/03 06:28:10 zender Exp $ */

/* Purpose: Arithmetic controls and utilities */

/* Copyright (C) 1995--2004 Charlie Zender
   This software may be modified and/or re-distributed under the terms of the GNU General Public License (GPL) Version 2
   See http://www.gnu.ai.mit.edu/copyleft/gpl.html for full license text */

#include "nco_rth_utl.h" /* Arithmetic controls and utilities */

void 
nco_opr_drv /* [fnc] Intermediate control of arithmetic operations for ncra/ncea */
(const long idx_rec, /* I [idx] Index of current record */
 const int nco_op_typ, /* I [enm] Operation type */
 const var_sct * const var_prc, /* I [sct] Variable in input file */
 var_sct * const var_prc_out) /* I/O [sct] Variable in output file */
{
  /* Purpose: Perform appropriate ncra/ncea operation (avg, min, max, ttl, ...) on operands
     nco_opr_drv() is called within the record loop of ncra, and within file loop of ncea
     These operations perform some, but not all, of necessary operations for each procedure
     Most arithmetic operations require additional procedures such as normalization be performed after all files/records have been processed */
  
  /* var_prc_out->type and var_prc->type should be equal and thus interchangeable
     var_prc_out->sz and var_prc->sz should be equal and thus interchangeable */
  switch (nco_op_typ){
  case nco_op_min: /* Minimum */
    /* On first loop, simply copy variables from var_prc to var_prc_out */
    if(idx_rec == 0) (void)var_copy(var_prc->type,var_prc->sz,var_prc->val,var_prc_out->val); else      
      (void)nco_var_min_bnr(var_prc_out->type,var_prc_out->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->val,var_prc_out->val);
    break;
  case nco_op_max: /* Maximium */
    /* On first loop, simply copy variables from var_prc to var_prc_out */
    if(idx_rec == 0) (void)var_copy(var_prc->type,var_prc->sz,var_prc->val,var_prc_out->val); else
      (void)nco_var_max_bnr(var_prc_out->type,var_prc_out->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->val,var_prc_out->val);
    break;  
  case nco_op_avg: /* Average */
  case nco_op_sqrt: /* Squareroot will produce the squareroot of the mean */
  case nco_op_ttl: /* Total */
  case nco_op_sqravg: /* Square of the mean */
    (void)nco_var_add_tll_ncra(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
    break;
  case nco_op_rms: /* Root mean square */
  case nco_op_rmssdn: /* Root mean square normalized by N-1 */
  case nco_op_avgsqr: /* Mean square */
    /* Square values in var_prc first */
    nco_var_mlt(var_prc->type,var_prc->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->val,var_prc->val);
    /* Sum the squares */
    (void)nco_var_add_tll_ncra(var_prc_out->type,var_prc_out->sz,var_prc->has_mss_val,var_prc->mss_val,var_prc->tally,var_prc->val,var_prc_out->val);
    break;
  } /* end switch */
} /* end nco_opr_drv() */

int /* O [enm] Arithmetic operation */
nco_op_typ_get /* [fnc] Convert user-specified operation into operation key */
(const char * const nco_op_sng) /* I [sng] User-specified operation */
{
  /* Purpose: Process '-y' command line argument
     Convert user-specified string to enumerated operation type */
  const char fnc_nm[]="nco_op_typ_get()"; /* [sng] Function name */
  char *prg_nm; /* [sng] Program name */
  int prg_id; /* [enm] Program ID */

  prg_nm=prg_nm_get(); /* [sng] Program name */
  prg_id=prg_get(); /* [enm] Program ID */

  if(nco_op_sng == NULL){
    /* If nco_op_typ_get() is called when user-specified option string is NULL, 
       then operation type may be implied by program name itself */
    if(!strcmp(prg_nm,"ncadd")) return nco_op_add;
    if(!strcmp(prg_nm,"ncbo")) return nco_op_sbt;
    if(!strcmp(prg_nm,"ncdiff")) return nco_op_sbt;
    if(!strcmp(prg_nm,"ncsub")) return nco_op_sbt;
    if(!strcmp(prg_nm,"ncsubtract")) return nco_op_sbt;
    if(!strcmp(prg_nm,"ncmult")) return nco_op_mlt;
    if(!strcmp(prg_nm,"ncmultiply")) return nco_op_mlt;
    if(!strcmp(prg_nm,"ncdivide")) return nco_op_dvd;
    (void)fprintf(stderr,"%s: ERROR %s reports empty user-specified operation string in conjunction with unknown or ambiguous executable name %s\n",prg_nm,fnc_nm,prg_nm);
    nco_exit(EXIT_FAILURE);
  } /* endif */

  if(!strcmp(nco_op_sng,"avg")) return nco_op_avg;
  if(!strcmp(nco_op_sng,"avgsqr")) return nco_op_avgsqr;
  if(!strcmp(nco_op_sng,"max")) return nco_op_max;
  if(!strcmp(nco_op_sng,"min")) return nco_op_min;
  if(!strcmp(nco_op_sng,"rms")) return nco_op_rms;
  if(!strcmp(nco_op_sng,"rmssdn")) return nco_op_rmssdn;
  if(!strcmp(nco_op_sng,"sqravg")) return nco_op_sqravg;
  if(!strcmp(nco_op_sng,"sqrt")) return nco_op_sqrt;
  if(!strcmp(nco_op_sng,"total") || !strcmp(nco_op_sng,"ttl")) return nco_op_ttl;

  if(!strcmp(nco_op_sng,"add") || !strcmp(nco_op_sng,"+") || !strcmp(nco_op_sng,"addition")) return nco_op_add;
  if(!strcmp(nco_op_sng,"sbt") || !strcmp(nco_op_sng,"-") || !strcmp(nco_op_sng,"dff") || !strcmp(nco_op_sng,"diff") || !strcmp(nco_op_sng,"sub") || !strcmp(nco_op_sng,"subtract") || !strcmp(nco_op_sng,"subtraction")) return nco_op_sbt;
  if(!strcmp(nco_op_sng,"dvd") || !strcmp(nco_op_sng,"/") || !strcmp(nco_op_sng,"divide") || !strcmp(nco_op_sng,"division")) return nco_op_dvd;
  if(!strcmp(nco_op_sng,"mlt") || !strcmp(nco_op_sng,"*") || !strcmp(nco_op_sng,"mult") || !strcmp(nco_op_sng,"multiply") || !strcmp(nco_op_sng,"multiplication")) return nco_op_mlt;

  (void)fprintf(stderr,"%s: ERROR %s reports unknown user-specified operation type %s\n",prg_nm,fnc_nm,nco_op_sng);
  (void)fprintf(stderr,"%s: HINT Valid operation type (op_typ) choices:\n",prg_nm);
  if(prg_id == ncbo) (void)fprintf(stderr,"addition: add,+,addition\nsubtration: sbt,-,dff,diff,sub,subtract,subtraction\nmultiplication: mlt,*,mult,multiply,multiplication\ndivision: dvd,/,divide,division\n"); else (void)fprintf(stderr,"min,max,ttl,total,sqrt,sqravg,avgsqr,rms,rmssdn");
  nco_exit(EXIT_FAILURE);
  return False; /* Statement should not be reached */
} /* end nco_op_typ_get() */

int /* O [enm] Relational operation */
nco_op_prs_rlt /* [fnc] Convert Fortran abbreviation for relational operator into NCO operation key */
(const char * const op_sng) /* I [sng] Fortran representation of relational operator */
{
  /* Purpose: Convert Fortran abbreviation for relational operator into NCO operation key */

  /* Classify the relation */
  if(!strcmp(op_sng,"eq")){
    return nco_op_eq;
  }else if(!strcmp(op_sng,"ne")){
    return nco_op_ne;
  }else if(!strcmp(op_sng,"lt")){
    return nco_op_lt;
  }else if(!strcmp(op_sng,"gt")){
    return nco_op_gt;
  }else if(!strcmp(op_sng,"le")){
    return nco_op_le;
  }else if(!strcmp(op_sng,"ge")){
    return nco_op_ge;
  }else{
    (void)fprintf(stdout,"%s: ERROR %s not registered in nco_op_prs_rlt()\n",prg_nm_get(),op_sng);
    nco_exit(EXIT_FAILURE);
  } /* end else */

  /* Some compilers, e.g., SGI cc, need return statement to end non-void functions */
  return False; /* Statement should not be reached */
} /* end nco_op_prs_rlt() */

void
vec_set /* [fnc] Fill every value of first operand with value of second operand */
(const nc_type type, /* I [enm] netCDF type of operand */
 const long sz, /* I [nbr] size (in elements) of operand */
 ptr_unn op1, /* I [sct] Values of first operand */
 const double op2) /* I [frc] Value to fill vector with */
{
  /* Purpose: Fill every value of first operand with value of second operand */
  long idx;

  /* Typecast pointer to values before access */
  (void)cast_void_nctype(type,&op1);
  switch(type){
  case NC_FLOAT:
    for(idx=0;idx<sz;idx++) op1.fp[idx]=op2;
    break;
  case NC_DOUBLE:
    for(idx=0;idx<sz;idx++) op1.dp[idx]=op2;
    break;
  case NC_INT:
    for(idx=0;idx<sz;idx++) op1.lp[idx]=(long)op2; /* Coerce to avoid C++ compiler assignment warning */
    break;
  case NC_SHORT:
    for(idx=0;idx<sz;idx++) op1.sp[idx]=(short)op2; /* Coerce to avoid C++ compiler assignment warning */
    break;
  case NC_CHAR:
    /* Do nothing */
    break;
  case NC_BYTE:
    /* Do nothing */
    break;
    default: nco_dfl_case_nc_type_err(); break;
  } /* end switch */

  /* NB: it is not neccessary to un-typecast pointers to values after access 
     because we have only operated on local copies of them. */

} /* end vec_set() */

void
nco_zero_long /* [fnc] Zero all values of long array */
(const long sz, /* I [nbr] Size (in elements) of operand */
 long * restrict const op1) /* I/O [nbr] Array to be zeroed */
{
  /* Purpose: Zero all values of long array */

  long idx;
  if(op1 == NULL){
    (void)fprintf(stdout,"%s: ERROR nco_zero_long() asked to zero NULL pointer\n",prg_nm_get());
    nco_exit(EXIT_FAILURE);
  } /* endif */
  for(idx=0;idx<sz;idx++) op1[idx]=0L;

} /* end nco_zero_long() */


Generated by  Doxygen 1.6.0   Back to index