예제 #1
0
static PGresult *
execPrepared(char *qName, List *values)
{
    char **params;
    int i;
    int nParams = LIST_LENGTH(values);
    PGresult *res = NULL;
    params = CALLOC(sizeof(char*),LIST_LENGTH(values));

    ASSERT(postgresIsInitialized());

    i = 0;
    FOREACH(Constant,c,values)
        params[i++] = STRING_VALUE(c);

    DEBUG_LOG("run query %s with parameters <%s>",
            qName, exprToSQL((Node *) values));

    res = PQexecPrepared(plugin->conn,
            qName,
            nParams,
            (const char *const *) params,
            NULL,
            NULL,
            0);

    if (PQresultStatus(res) != PGRES_TUPLES_OK)
        CLOSE_RES_CONN_AND_FATAL(res, "query %s failed:\n%s", qName,
                PQresultErrorMessage(res));

    return res;
}
예제 #2
0
파일: treeview.c 프로젝트: Airr/Claro
int treeview_get_rows( object_t *obj, list_item_t *parent )
{
	list_widget_t *lw = (list_widget_t *)obj;
	
	assert_valid_treeview_widget( obj, "obj" );
	assert_only_list_item( parent, "parent" );
	
	if ( parent == 0 )
		return LIST_LENGTH( &lw->items );
	
	return LIST_LENGTH( &parent->children );
}
예제 #3
0
파일: list.c 프로젝트: dayu070/GProm
ListCell *
popHeadOfList(List *list)
{
    ListCell *result = LIST_LENGTH(list) > 0 ? list->head : NULL;

    if (LIST_LENGTH(list) > 0)
    {
        list->length--;
        list->head = result->next;
    }

    return result;
}
예제 #4
0
DataType
postgresGetFuncReturnType (char *fName, List *argTypes)
{
    PGresult *res = NULL;
    DataType resType = DT_STRING;

    ACQUIRE_MEM_CONTEXT(memContext);

    //TODO cache operator information
    res = execPrepared(NAME_GET_FUNC_DEFS,
            LIST_MAKE(createConstString(fName),
                    createConstInt(LIST_LENGTH(argTypes))));

    for(int i = 0; i < PQntuples(res); i++)
    {
        char *retType = PQgetvalue(res,i,0);
        char *argTypes = PQgetvalue(res,i,1);
        List *argDTs = oidVecToDTList(argTypes);

        if (equal(argDTs, argTypes)) //TODO compatible data types
            return postgresOidToDT(retType);
    }

    PQclear(res);

    RELEASE_MEM_CONTEXT();

    return resType;
}
예제 #5
0
파일: set.c 프로젝트: danopia/atheme
static void bs_cmd_set_nobot(sourceinfo_t *si, int parc, char *parv[])
{
	char *channel = parv[0];
	char *option = parv[1];
	mychan_t *mc;
	metadata_t *md;

	if (parc < 2 || !channel || !option)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "SET NOBOT");
		command_fail(si, fault_needmoreparams, _("Syntax: SET <#channel> NOBOT {ON|OFF}"));
		return;
	}

	mc = mychan_find(channel);
	if (!mc)
	{
		command_fail(si, fault_nosuch_target, _("Channel \2%s\2 is not registered."), channel);
		return;
	}

	if (!si->smu)
	{
		command_fail(si, fault_noprivs, _("You are not logged in."));
		return;
	}

	if (!has_priv(si, PRIV_CHAN_ADMIN))
	{
		command_fail(si, fault_noprivs, _("You are not authorized to perform this operation."));
		return;
	}

	if (!irccasecmp(option, "ON"))
	{
		metadata_add(mc, "private:botserv:no-bot", "ON");
		if ((md = metadata_find(mc, "private:botserv:bot-assigned")) != NULL)
		{
			if (mc->flags & MC_GUARD &&
					(!config_options.leave_chans ||
					 (mc->chan != NULL &&
					  LIST_LENGTH(&mc->chan->members) > 1)))
				join(mc->name, chansvs.nick);
			part(mc->name, md->value);
			metadata_delete(mc, "private:botserv:bot-assigned");
			metadata_delete(mc, "private:botserv:bot-handle-fantasy");
		}
		command_success_nodata(si, _("No Bot mode is now \2ON\2 on channel %s."), mc->name);
	}
	else if(!irccasecmp(option, "OFF"))
	{
		metadata_delete(mc, "private:botserv:no-bot");
		command_success_nodata(si, _("No Bot mode is now \2OFF\2 on channel %s."), mc->name);
	}
	else
	{
		command_fail(si, fault_badparams, STR_INVALID_PARAMS, "SET NOBOT");
		command_fail(si, fault_badparams, _("Syntax: SET <#channel> NOBOT {ON|OFF}"));
	}
}
예제 #6
0
파일: utils.c 프로젝트: markjreed/vice-emu
unsigned av_int_list_length_for_size(unsigned elsize,
                                     const void *list, uint64_t term)
{
    unsigned i = 0;

    if (!list)
        return 0;
#define LIST_LENGTH(type) \
    { type t = term, *l = (type *)list; for (i = 0; l[i] != t; i++); }
    switch (elsize) {
    case 1: LIST_LENGTH(uint8_t);  break;
    case 2: LIST_LENGTH(uint16_t); break;
    case 4: LIST_LENGTH(uint32_t); break;
    case 8: LIST_LENGTH(uint64_t); break;
    default: av_assert0(!"valid element size");
    }
    return i;
}
예제 #7
0
int menubar_item_count( object_t *obj, list_item_t *parent )
{
	list_widget_t *lw = (list_widget_t *)obj;
	
	assert_valid_menubar_widget( obj, "obj" );
	assert_only_list_item( parent, "parent" );
	
	return LIST_LENGTH( &lw->items );
}
예제 #8
0
파일: cascade.c 프로젝트: macssh/macssh
static void do_cascade_crypt(struct crypto_instance *s,
			     UINT32 length, const UINT8 *src, UINT8 *dst)
{
  CAST(crypto_cascade_instance, self, s);
  unsigned i;
  
  if (length % self->super.block_size)
    fatal("Internal error!\n");

  assert(LIST_LENGTH(self->cascade));

  {
    CAST_SUBTYPE(crypto_instance, o, LIST(self->cascade)[0]);
    CRYPT(o, length, src, dst);
  }
  for (i = 1; i<LIST_LENGTH(self->cascade); i++)
    {
      CAST_SUBTYPE(crypto_instance, o, LIST(self->cascade)[i]);
      CRYPT(o, length, dst, dst);
    }
}
예제 #9
0
void
printSingleECList(List *l)
{
	DEBUG_LOG("SET LIST: %s, SIZE LIST %d", nodeToString(l), LIST_LENGTH(l));
	FOREACH(KeyValue, kv, l)
	{
	    Set *s = (Set *) kv->key;
	    Constant *c = (Constant *) kv->value;
		DEBUG_LOG("Set: ");
		FOREACH_SET(char, n, s)
        {
		    DEBUG_LOG("%s", (char *)n);
        }
예제 #10
0
파일: spki.c 프로젝트: macssh/macssh
static int
do_spki_tag_set_match(struct spki_tag *s,
		      struct sexp *e)
{
  CAST(spki_tag_set, self, s);
  unsigned i;

  for (i = 0; i<LIST_LENGTH(self->set); i++)
    {
      CAST_SUBTYPE(spki_tag, tag, LIST(self->set)[i]);
      if (SPKI_TAG_MATCH(tag, e))
	return 1;
    }

  return 0;
}
예제 #11
0
파일: cascade.c 프로젝트: macssh/macssh
struct crypto_algorithm *crypto_cascadel(struct object_list *cascade)
{
  NEW(crypto_cascade_algorithm, self);
  unsigned i;
  
  self->cascade = cascade;

  self->super.key_size = self->super.iv_size = 0;
  self->super.block_size = 1;

  for (i = 0; i<LIST_LENGTH(self->cascade); i++)
    {
      CAST_SUBTYPE(crypto_algorithm, a, LIST(self->cascade)[i]);
      self->super.key_size += a->key_size;
      self->super.iv_size += a->iv_size;
      self->super.block_size = lcm(self->super.block_size, a->block_size);
    }

  self->super.make_crypt = do_make_cascade;

  return &self->super;
} 
예제 #12
0
파일: cascade.c 프로젝트: macssh/macssh
static struct crypto_instance *
do_make_cascade(struct crypto_algorithm *s,
		int mode, const UINT8 *key, const UINT8 *iv)
{
  CAST(crypto_cascade_algorithm, algorithm, s);
  NEW(crypto_cascade_instance, instance);
  unsigned i;
  unsigned l = LIST_LENGTH(algorithm->cascade);
  
  instance->super.block_size = algorithm->super.block_size;
  instance->cascade = alloc_object_list(l);

  for (i = 0; i<l; i++)
    {
      /* When decrypting, the crypto algorithms should be used in
       * reverse order! */

      unsigned j = ( (mode == CRYPTO_ENCRYPT)
		     ? i : l - i - 1);
      
      CAST_SUBTYPE(crypto_algorithm, a, LIST(algorithm->cascade)[i]);
      struct crypto_instance *o	= MAKE_CRYPT(a, mode, key, iv);
      
      if (!o)
	{
	  KILL(instance);
	  return NULL;
	}

      LIST(instance->cascade)[j] = (struct lsh_object *) o;
      key += a->key_size;
      iv += a->iv_size;
    }

  instance->super.crypt = do_cascade_crypt;
  
  return &instance->super;
}
예제 #13
0
DataType
postgresGetOpReturnType (char *oName, List *argTypes)
{
    PGresult *res = NULL;
    DataType resType = DT_STRING;

    ACQUIRE_MEM_CONTEXT(memContext);

    //TODO cache operator information
    res = execPrepared(NAME_GET_OP_DEFS,
            LIST_MAKE(createConstString(oName),
                    createConstInt(LIST_LENGTH(argTypes))));

    for(int i = 0; i < PQntuples(res); i++)
    {

    }

    PQclear(res);
    RELEASE_MEM_CONTEXT();

    return resType;
}
예제 #14
0
파일: spki.c 프로젝트: macssh/macssh
static int
do_spki_tag_list_match(struct spki_tag *s,
		       struct sexp *e)
{
  CAST(spki_tag_list, self, s);
  unsigned i;
  struct sexp_iterator *j;
  
  if (sexp_atomp(e))
    return 0;

  for (i = 0, j = SEXP_ITER(e);
       i<LIST_LENGTH(self->list);
       i++, SEXP_NEXT(j))
    {
      CAST_SUBTYPE(spki_tag, tag, LIST(self->list)[i]);
      struct sexp *o = SEXP_GET(j);

      if (! (o && SPKI_TAG_MATCH(tag, o)))
	return 0;
    }
  
  return 1;
}
예제 #15
0
파일: toolbar.c 프로젝트: Airr/Claro
void cgraphics_toolbar_new_icon( widget_t *widget, list_item_t *item )
{
	widget_t *parent = (widget_t *)OBJECT(widget)->parent;
	HWND rebar = parent->ndata;
	REBARBANDINFO ri;
	TBADDBITMAP tbb;
	TBBUTTON tbut;
	DWORD dwBtnSize;
	node_t *n;
	image_t *img = item->data[0];
	const char *txt = item->data[1];
	
	if ( img == 0 && txt == 0 )
	{
		/* regardless of style, this is a separator :) */
		tbut.iBitmap = 10;
		tbut.fsStyle = BTNS_SEP;
		tbut.iString = 0; /* JIC */
	}
	else
	{
		/* it has SOMETHING filled in, so let's tell Windows */
		
		tbut.fsStyle = BTNS_BUTTON;
		tbb.hInst = NULL;
		tbb.nID = 0;
		
		if ( widget->flags & cToolbarAutoSizeButtons )
			tbut.fsStyle |= BTNS_AUTOSIZE;
		
		if ( LIST_LENGTH( &item->children ) > 0 )
			tbut.fsStyle |= BTNS_DROPDOWN;
		
		if ( widget->flags & cToolbarShowImages )
		{
			tbb.hInst = NULL;
#ifdef IMAGES_USE_LIBPNG
			tbb.nID = 0;
			tbut.iBitmap = 0;
#else
			tbb.nID = (UINT_PTR)img->native2; // BMP
			
			a = SendMessage( widget->native, TB_ADDBITMAP, 1, (LPARAM)&tbb );
			
			tbut.iBitmap = a;
#endif
		}
		
		if ( widget->flags & cToolbarShowText )
		{
			tbut.iString = (size_t)txt;
			tbut.fsStyle |= BTNS_SHOWTEXT;
		}
		else
			tbut.iString = 0;
	}
	
	/* if none so far, just for safely clean the list :) */
	if ( tblist_cmdid == 0 ) {
		tblist_cmdid++;
		list_create( &tblist );
	}
	
	/* that's our cmdid! prepare the next one, too.. */
	item->nativeid = tblist_cmdid;
	tblist_cmdid++;
	
	/* save into cmdid mapping list */
	n = node_create( );
	node_add( item, n, &tblist );
	
	tbut.idCommand = item->nativeid;
	tbut.fsState = TBSTATE_ENABLED;
	tbut.dwData = 0;
	
	SendMessage( widget->native, TB_INSERTBUTTON, item->row, (LPARAM)&tbut );
	
	/* Fix the rebar :) */
	
	SendMessage( widget->native, TB_AUTOSIZE, 0, 0 );
	
	dwBtnSize = SendMessage( widget->native, TB_GETBUTTONSIZE, 0, 0 );
	
	ZeroMemory( &ri, sizeof(ri) );
	ri.cbSize = sizeof(REBARBANDINFO);
	ri.fMask  = RBBIM_CHILDSIZE;
	
	ri.cxMinChild = 0;
	ri.cyMinChild = HIWORD(dwBtnSize);
	ri.cx         = 10;

	SendMessage( rebar, RB_SETBANDINFO, (WPARAM)0, (LPARAM)&ri );
}
예제 #16
0
파일: drop.c 프로젝트: danopia/atheme
static void ns_cmd_drop(sourceinfo_t *si, int parc, char *parv[])
{
	myuser_t *mu;
	mynick_t *mn;
	char *acc = parv[0];
	char *pass = parv[1];

	if (!acc || !pass)
	{
		command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DROP");
		command_fail(si, fault_needmoreparams, _("Syntax: DROP <account> <password>"));
		return;
	}

	if (!(mu = myuser_find(acc)))
	{
		if (!nicksvs.no_nick_ownership)
		{
			mn = mynick_find(acc);
			if (mn != NULL && command_find(si->service->cmdtree, "UNGROUP"))
			{
				command_fail(si, fault_nosuch_target, _("\2%s\2 is a grouped nick, use %s to remove it."), acc, "UNGROUP");
				return;
			}
		}
		command_fail(si, fault_nosuch_target, _("\2%s\2 is not registered."), acc);
		return;
	}

	if (metadata_find(mu, "private:freeze:freezer"))
	{
		command_fail(si, fault_authfail, nicksvs.no_nick_ownership ? "You cannot login as \2%s\2 because the account has been frozen." : "You cannot identify to \2%s\2 because the nickname has been frozen.", mu->name);
		return;
	}

	if (!verify_password(mu, pass))
	{
		command_fail(si, fault_authfail, _("Authentication failed. Invalid password for \2%s\2."), mu->name);
		bad_password(si, mu);
		return;
	}

	if (!nicksvs.no_nick_ownership &&
			LIST_LENGTH(&mu->nicks) > 1 &&
			command_find(si->service->cmdtree, "UNGROUP"))
	{
		command_fail(si, fault_noprivs, _("Account \2%s\2 has %d other nick(s) grouped to it, remove those first."),
				mu->name, LIST_LENGTH(&mu->nicks) - 1);
		return;
	}

	if (is_soper(mu))
	{
		command_fail(si, fault_noprivs, _("The nickname \2%s\2 belongs to a services operator; it cannot be dropped."), acc);
		return;
	}

	if (mu->flags & MU_HOLD)
	{
		command_fail(si, fault_noprivs, _("The account \2%s\2 is held; it cannot be dropped."), acc);
		return;
	}

	snoop("DROP: \2%s\2 by \2%s\2", mu->name, get_source_name(si));
	command_add_flood(si, FLOOD_MODERATE);
	logcommand(si, CMDLOG_REGISTER, "DROP %s", mu->name);
	hook_call_user_drop(mu);
	command_success_nodata(si, _("The account \2%s\2 has been dropped."), mu->name);
	object_unref(mu);
}
예제 #17
0
void SPC_HIERARCHICAL(edge_t * V, nid_t n, int d, int k, nid_t minClusSize, int Nmc, int * Nc, nid_t ** Cn, nid_t *** C, nid_t ** P)
{
    // Declare variables
    FS_TREE * FST;
  	Graph * D, * MSG, * Tb;
    edge_t tmin, tmax, aKi, aWs, ival, b_thresh, tval, maxval, cval, Tsp;
    edge_t minTempStep, minTempStep_end, ta, tb, tc, Tspa;
    edge_t * Teval;
    nid_t tid, maxid, mcid, Sma, Smb, Smc, cid, cid2, tcs;
    nid_t * maxCor, * Ct, * MCS, * MCI, * newC;
    List * S;  
    int i, j, l, init_temps, ei, scan_temps, scan_print, ilc, ncf, Njumps;
    int p, jj, maxPosClusts, llci, hier_print, plt, nsplits;
    int SI[1000]; 
    int ** Ch;
    int * ChN, * newCh;


    //0. Find the fair-split tree
    //mexPrintf("Computing fair-split tree...\n"); mexEvalString("drawnow;");
    FST = FAIR_SPLIT(V, n, d); //compute the fair split tree
    //mexPrintf("  Finished.\n"); mexEvalString("drawnow;");


    // 1. Find mutual K Nearest Neighbors
    mexPrintf("Finding mutual K Nearest Neighbors...\n"); mexEvalString("drawnow;");
    D = NEW_ALGRAPH(n,0); //graph of distances between mutual KNN
    FS_AMKNN(FST, D, n, k); //compute the approx MKNN using the fair-split tree
    mexPrintf("  Finished.\n"); mexEvalString("drawnow;");


    // 2. Find Approximate Minimum Spanning Graph
    //mexPrintf("Approximating the minimum spanning graph...\n"); mexEvalString("drawnow;");
    MSG = NEW_ALGRAPH(n,0); //allocate new graph for min span graph
    FS_AEMSG(FST, MSG); //compute approx. min spanning graph using fair-split tree
    //mexPrintf("  Finished.\n"); mexEvalString("drawnow;");
    CLEAR_FS_TREE(FST); //don't need the tree anymore


    // 3. Superimpose KNN and MST
    ALG_ORIP(D, MSG); //OR the edges of each graph, store in D
    ALG_CLEAR(MSG); //free the MST from mem


    // 4. Calculate interaction values between each neighbor
    b_thresh = 0.5; //probability threshold for edge
    aKi = 1.0/(2.0*((float) D->ne)/((float) D->n)); //inverse of avg. number of neighbors
    aWs = ALG_AVG_EDGE_WEIGHT(D); //the average distance between neighbors
    aWs = 2.0*aWs*aWs; //twice the squared average distance between neighbors
    Tb = NEW_ALGRAPH(n, 0); //allocate new graph for break temps
    for (i=0;  i<D->n; i++) { //for each node
        for (j=0; j<LIST_LENGTH(D->nodes[i]); j++) { //for each edge from that node
            tid = LIST_GET_ID(D->nodes[i], j); //id of edge's endpoint
            if (i < tid) { //undir graph, so only worry about lesser->larger id edges
                tval = LIST_GET_VAL(D->nodes[i], j); //distance between i and tid
                ival = aKi*exp(-tval*tval/aWs); //this interaction strength
                ival = -ival/log(1.0-b_thresh); //the temp above which this edge breaks
                ival = 1e3*ival*ival*ival; //cubing it and *1k seems to work well just to get a more linear eval
                if (ival > tmax) tmax = ival; //store max edge val
                if (ival < tmin) tmin = ival; //store min val
                ALG_ADD_EDGE(Tb, i, tid, ival); //add the interaction to the graph
            }
        }
    }


    // Get the max-correlation neighbor of each point
    maxCor = malloc(Tb->n * sizeof(nid_t)); //id of the max-cor point for each point
    for (i=0; i<Tb->n; i++) { //for each node
        maxid = 0;
        maxval = 0;
        for (j=1; j<LIST_LENGTH(Tb->nodes[i]); j++) { //for each edge
            mcid = LIST_GET_ID(Tb->nodes[i], j); //get this child's id
            cval = LIST_GET_VAL(Tb->nodes[i], j); //get child's value
            if (cval > maxval) {
                maxval = cval;
                maxid = mcid;
            }
        }
        maxCor[i] = maxid;
    }
    

    // 5. Guestimate SPM-to-Paramagnetic phase transition temperature
    Tsp = tmax;


    // 6. Evaluate at the theoretical SPM->PM temp
    init_temps = 100;
    ei = 0;  //index of current evaluation
    S = NEW_LIST(10); //dfs stack of nodes to visit during subgraphs search
    Teval = malloc(init_temps*sizeof(edge_t)); //temps which were evaluated
    Ct = malloc(n*init_temps*sizeof(nid_t)); //clusterids at each temp
    MCS = malloc(Nmc*init_temps*sizeof(nid_t)); //max cluster sizes
    MCI = malloc(Nmc*init_temps*sizeof(nid_t)); //ids of the max clusters
    THRESH_SUBGRAPHS_SIZES(Tb, maxCor, Tsp, Nmc, S, Ct, MCS, MCI); //find the cluster ids and sizes of the largest clusters at the theoretical temp
    *Teval = Tsp; //store where we evaluated at
    ei++; //increment evaluation index

    // 6.5 "Evaluate" at T=0
    for (i=0; i<n; i++) { *(Ct+n+i) = 1; } //all points are of the same cluster
    for (i=1; i<Nmc; i++) { *(MCI+Nmc+i) = -1; } //all points are of the same cluster
    for (i=1; i<Nmc; i++) { *(MCS+Nmc+i) = 0; } //all other cluster sizes are 0
    *(MCS+Nmc) = n; //at lowest temp, largest cluster consists of all points
    *(MCI+Nmc) = 1; //and it has id of 1
    *(Teval+1) = 0.0;
    ei++;


    // 7. Find the true SPM->PM phase transition temperature
    //mexPrintf("Finding true SPM->PM temp...\n");
    minTempStep_end = Tsp/100;
    ta=0; tb=Tsp; //bound temps for binary search
    Sma=n; Smb=*MCS; //max cluster size at bound temps
    while ( tb-ta > minTempStep_end ) {
        if ( Smb > minClusSize ) { //SPM->PM temp is above our bracket
            ta = tb; //set A to B
            Sma = Smb; //set A to B
            tb = 2*tb; //extend bracket range
            *(Teval+ei) = tb; //evaluate at new T
            THRESH_SUBGRAPHS_SIZES(Tb, maxCor, tb, Nmc, S, Ct+ei*n, MCS+ei*Nmc, MCI+ei*Nmc);
            Smb = *(MCS+ei*Nmc); //store the max cluster size @ that temp
        } else { //SPM->PM temp is below top bracket
            tc = (ta+tb)/2; //midpoint temperature between brackets
            *(Teval+ei) = tc; //evaluate at midpoint
            THRESH_SUBGRAPHS_SIZES(Tb, maxCor, tc, Nmc, S, Ct+ei*n, MCS+ei*Nmc, MCI+ei*Nmc);
            Smc = *(MCS+ei*Nmc); //store the max cluster size @ that temp
            if ( Smc < minClusSize ) { //SPM->PM is between A and C
                tb = tc; //set B to C
                Smb = Smc;
            } else { //SPM->PM is between C and B
                ta = tc; //set A to C
            }
        }
        ei++; //increment evaluation index
        if (ei >= init_temps) { //double array sizes if we need more space
            doubleArraySizes(&Teval, &Ct, &MCS, &MCI, &init_temps, n, Nmc);
        }
    }
    Tspa = tb; //the actual SPM->PM transtion temperature
    //mexPrintf("  Finished.\n");


    // 8. Do an initial scan across temperatures
    scan_temps = 50;  
    scan_print = scan_temps/10;
    mexPrintf("Performing initial scan over temperatures...\n"); mexEvalString("drawnow;");
    for (i=1; i<scan_temps; i++) {
        tc = i*Tspa/scan_temps; //linspace from 0 to SPM->PM
        *(Teval+ei) = tc; //evaluate at each temp
        THRESH_SUBGRAPHS_SIZES(Tb, maxCor, tc, Nmc, S, Ct+ei*n, MCS+ei*Nmc, MCI+ei*Nmc);
        ei++;
        if (ei >= init_temps) { //double array sizes if we need more space
            doubleArraySizes(&Teval, &Ct, &MCS, &MCI, &init_temps, n, Nmc);
        }
    scan_print = scan_temps/10;
        if (i%scan_print==0) { //print progress
            //mexPrintf("  %.1f percent complete\n", 100 * (float) i / (float) scan_temps);
            //mexEvalString("drawnow;");
        }
    }
    mexPrintf("  Finished.\n"); mexEvalString("drawnow;");


    // 9. Find the jump points for each i-th largest cluster
    minTempStep = Tspa/800;
    Njumps = 0;  //number of jumps so far
    printf("Zooming in on cluster splits...\n"); mexEvalString("drawnow;");
    for (ilc=1; ilc<Nmc; ilc++) {  //for each of the i-th largest clusters
        //printf("  Looking for %d-largest cluster jumps (out of %d)...\n", ilc+1, Nmc);  ncf = 1;
        //mexEvalString("drawnow;");
        sortTemps(Teval, ei, SI); //get the order of Teval in SI
        i = 1;
        while ( Teval[SI[i]] < Tspa ) { //while we haven't reached the SPM->PM temp
            if ( ( *(MCS+Nmc*SI[i]+ilc) > *(MCS+Nmc*SI[i-1]+ilc) ) //if i-th largest cluster increased in size since last timestep
              && ( *(MCS+Nmc*SI[i]+ilc) > minClusSize ) // and it's not too small,
              && ( Teval[SI[i]]-Teval[SI[i-1]] > minTempStep ) ) { // and we haven't already zoomed in here
                // Then do a binary search for jump point between these two points!
                //printf("    Found total of %d, this one at T=%f\n", ncf++, Teval[SI[i]]);
                //mexEvalString("drawnow;");
                ta = Teval[SI[i-1]];  tb = Teval[SI[i]]; //bracket the jump point
                Sma = *(MCS+Nmc*SI[i-1]+ilc);
                Smb = *(MCS+Nmc*SI[i]+ilc);
                while ( tb-ta > minTempStep ) {
                    tc = (ta+tb)/2; //midpoint
                    *(Teval+ei) = tc; //evaluate at midpoint
                    THRESH_SUBGRAPHS_SIZES(Tb, maxCor, tc, Nmc, S, Ct+ei*n, MCS+ei*Nmc, MCI+ei*Nmc);
                    Smc = *(MCS+ei*Nmc+ilc); //store the max cluster size @ that temp
                    ei++;
                    if (ei >= init_temps) { //double array sizes if we need more space
                        doubleArraySizes(&Teval, &Ct, &MCS, &MCI, &init_temps, n, Nmc);
                    }
                    if (Sma < Smc && Smc > minClusSize) { //there is a jump between A and C and C is above size threshold
                        tb = tc; //set B to C
                        Smb = Smc;
                    } else { //jump point is between C and B
                        ta = tc;  //set A to C
                        Sma = Smc;
                    }
                }
                sortTemps(Teval, ei, SI); //get the order of Teval in SI
            }
            i++; //move on to next temp step
        }
    }
    printf("  Finished.\n"); mexEvalString("drawnow;");

    printf("\nRan %d evaluations total\n\n", ei); mexEvalString("drawnow;");


    // 10. Find the clusters which have jumped at each jump point, and hierarchical structure
    //printf("Determining hierarchical structure of clusters...\n");
    maxPosClusts = 200; //not gonna be more than that many clusters, right?
    *Nc = 0;
    *Cn = malloc(maxPosClusts*sizeof(nid_t)); //allocate list of cluster sizes
    *C = malloc(maxPosClusts*sizeof(nid_t *)); //allocate list of pointers to cluster id lists
    *P = malloc(maxPosClusts*sizeof(nid_t)); //allocate list of parent cluster ids
    Ch = malloc(maxPosClusts*sizeof(nid_t *)); //list of pointers to child list for each cluster
    for (p=0; p<maxPosClusts; p++) { //initialize to null
        Ch[p] = NULL;
    }
    ChN = malloc(maxPosClusts*sizeof(nid_t)); //number of children for each cluster
    for (p=0; p<maxPosClusts; p++) { //initialize to zero
        ChN[p] = 0;
    }
    llci = 0; //index of the temp of the last break from the largest clus
    hier_print = ei/5;

    for (i=1; i<ei; i++) { //for each evaluation,

        //if (i%hier_print==0) { //print progress occasionally
        //    printf("  %.1f percent complete\n", 100.0 * ((float) i) / ((float) ei));
        //}

        // If the gap is small enough, there may be a split here
        if ( Teval[SI[i]]-Teval[SI[i-1]] < 2*minTempStep ) { 
            nsplits = 0;
            for (j=0; j<Nmc; j++) { //for each of the i-th largest clusters

                // Find which cluster at the last tempstep was its parent
                plt = -1; //parent id at the last temperature
                for (jj=Nmc-1; jj>=0 && plt<0; jj--) {
                    if (isChild(j, i, jj, i-1, MCI, Nmc, SI, Ct, n)) { 
                        plt = jj;
                    }
                }

                // Was there a jump?
                tcs = *(MCS+Nmc*SI[i]+j); //this cluster's size at current temp
                if ((*(MCS+Nmc*SI[i-1]+plt)-tcs) > minClusSize && tcs>minClusSize) { //if there was a jump and this cluster is large enough to consider

                    // Make a new cluster of clus(j,i)
                    nsplits++; //count the number of clusters which split
                    newC = malloc(tcs*sizeof(nid_t)); //list of cluster IDs for the new cluster
                    (*C)[*Nc] = newC; //make corresponding element of C point to that list
                    (*Cn)[*Nc] = tcs; //store the size of the new cluster
                    cid2 = 0; //reset counter
                    for (cid=0; cid<n; cid++) { //for each point,
                        //if this point is in the new cluster
                        if ( *(Ct+n*SI[i]+cid) == *(MCI+Nmc*SI[i]+j) ) { 
                            newC[cid2++] = cid; //store the ids of each point in the cluster
                        }
                    }
                    (*Nc)++; //increment the number of clusters found
                    
                    // Find its parent in the list of existing clusters
                    p = parentSearch(newC, tcs, *C, *Cn, *P, *Nc-1); 
                    (*P)[*Nc-1] = p; //set element in P to the parent clus id of new clus 
                    
                    // Print info
                    //printf("At T=%f, cluster id=%d of size %d broke off from %d\n", Teval[SI[i]], *Nc-1, tcs, p);

                }
            }

            if (nsplits == 1) { //can't have just one! Need to have two which split off
                //so delete the most recently added cluster
                free(newC);
                (*Nc)--; //decrement the number of clusters found
                (*C)[*Nc] = NULL; //make corresponding element of C point to that list
                (*Cn)[*Nc] = -1; //store the size of the new cluster
            }
        }
    }
    //printf("  Finished.\n"); mexEvalString("drawnow;");


    // Done, clean up
    ALG_CLEAR(Tb);
    CLEAR_LIST(S);
    free(maxCor);
    free(Teval);
    free(Ct); 
    free(MCS);
    free(MCI);
    mexPrintf("Done.\n");

}