コード例 #1
0
ファイル: clustering_coef_wu.cpp プロジェクト: kbxu/bct-cpp
/*
 * Computes the clustering coefficient for a weighted undirected graph.
 */
VECTOR_T* BCT_NAMESPACE::clustering_coef_wu(const MATRIX_T* W) {
    if (safe_mode) check_status(W, SQUARE | WEIGHTED | UNDIRECTED, "clustering_coef_wu");

    // K=sum(W~=0,2);
    MATRIX_T* W_neq_0 = compare_elements(W, fp_not_equal, 0.0);
    VECTOR_T* K = sum(W_neq_0, 2);
    MATRIX_ID(free)(W_neq_0);

    // cyc3=diag((W.^(1/3))^3);
    MATRIX_T* W_pow_1_3 = pow_elements(W, 1.0 / 3.0);
    MATRIX_T* W_pow_1_3_pow_3 = pow(W_pow_1_3, 3);
    MATRIX_ID(free)(W_pow_1_3);
    VECTOR_ID(view) cyc3 = MATRIX_ID(diagonal)(W_pow_1_3_pow_3);

    // K(cyc3==0)=inf;
    VECTOR_T* cyc3_eq_0 = compare_elements(&cyc3.vector, fp_equal, 0.0);
    logical_index_assign(K, cyc3_eq_0, GSL_POSINF);
    VECTOR_ID(free)(cyc3_eq_0);

    // C=cyc3./(K.*(K-1));
    VECTOR_T* K_sub_1 = copy(K);
    VECTOR_ID(add_constant)(K_sub_1, -1.0);
    VECTOR_ID(mul)(K, K_sub_1);
    VECTOR_ID(free)(K_sub_1);
    VECTOR_T* C = copy(&cyc3.vector);
    MATRIX_ID(free)(W_pow_1_3_pow_3);
    VECTOR_ID(div)(C, K);
    VECTOR_ID(free)(K);

    return C;
}
コード例 #2
0
ファイル: simplex.c プロジェクト: marso329/courses
void remove_variables(problem* prob, matrix* tableau){
  /* Remove vars from inequality constraints */
  size_t temp_col = prob->variable_count*2 + prob->inequality_count + prob->equality_count + 1;

  size_t r;
  for (r = prob->equality_count+1; r <= tableau->rows-1; r++){
    if (temp_col >= tableau->columns){
      break;
    } else if (compare_elements(get_value_without_check(r, temp_col, tableau), 0) == 0){
      continue;
    }
    /* Removes virtual variable from objective function */
    matrix* temp_row = get_row_vector_with_return(r, tableau);
    multiply_matrix_with_scalar(-1, temp_row);
    matrix* temp_obj = get_row_vector_with_return(tableau->rows, tableau);
    matrix* new_obj = add_matrices_with_return(temp_row, temp_obj);
    insert_row_vector(tableau->rows, new_obj, tableau);

    /* Free help matrices */
    free_matrix(temp_row);
    free_matrix(temp_obj);
    free_matrix(new_obj);

    /* Next var */
    temp_col++;
  }
}
コード例 #3
0
ファイル: simplex.c プロジェクト: marso329/courses
/* Checks if all the elements in a row in the simplex tableau is negative or zero */
bool is_neg_tableau_row(int row, matrix* tableau){
  size_t c;
  for (c = 1; c <= tableau->columns; c++){
    if (compare_elements(get_value_without_check(row, c, tableau), 0) == 1){
      return false;
    }
  }
  return true;
}
コード例 #4
0
ファイル: simplex.c プロジェクト: marso329/courses
/* Returns the row with smallest RHS/(LHS element in choosen column), for simplex phase I*/
int min_test(int column, matrix* tableau){
  value temp, cur;
  bool first = true;
  int min_row = -1;
  size_t r;
  for (r = 1; r < tableau->rows; r++){
    temp = get_value_without_check(r, column, tableau);
    if (compare_elements(temp, 0) == 1){
      temp = get_value_without_check(r, tableau->columns, tableau)/temp;
      if (first){
        min_row = r;
        cur = temp;
        first = false;
      }else if (compare_elements(temp, cur) == -1){
        min_row = r;
        cur = temp;
      }
    }
  }
  return min_row;
}
コード例 #5
0
ファイル: simplex.c プロジェクト: marso329/courses
void neg_equality(problem* prob, work_set* virtual_vars){
  /* Negatate all equality constraints where RHS is negative */
  if (prob->equality_count > 0){  
    size_t r;
    for (r = 1; r <= prob->equality_count; r++){
      if (compare_elements(get_value_without_check(r, 1, prob->h), 0) == -1){
        multiply_row_with_scalar(-1, r, prob->E);
        multiply_row_with_scalar(-1, r, prob->h);
      }
      /* Add virtual variable */
      work_set_append(virtual_vars, r);
    }
  }
}
コード例 #6
0
ファイル: vertexdeclaration.c プロジェクト: devyn/wine
static HRESULT test_fvf_to_decl(
    IDirect3DDevice9* device,
    IDirect3DVertexDeclaration9* default_decl,
    DWORD test_fvf,
    const D3DVERTEXELEMENT9 expected_elements[],
    char object_should_change) 
{

    HRESULT hr;
    IDirect3DVertexDeclaration9 *result_decl = NULL;

    /* Set a default declaration to make sure it is changed */
    hr = IDirect3DDevice9_SetVertexDeclaration ( device, default_decl );
    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) goto fail;

    /* Set an FVF */
    hr = IDirect3DDevice9_SetFVF( device, test_fvf);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) goto fail;

    /* Check if the declaration object changed underneath */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) goto fail;
    if (object_should_change) {
       ok(result_decl != default_decl, "result declaration matches original\n");
       if (result_decl == default_decl) goto fail;
    } else {
       ok(result_decl == default_decl, "result declaration does not match original\n");
       if (result_decl != default_decl) goto fail;
    }

    /* Declaration content/size test */
    ok(result_decl != NULL, "result declaration was null\n");
    if (result_decl == NULL) 
        goto fail;
    else if (compare_elements(result_decl, expected_elements) != S_OK)
        goto fail;

    if (result_decl) IUnknown_Release( result_decl );
    return S_OK;    

    fail:
    if (result_decl) IUnknown_Release( result_decl );
    return E_FAIL;
}
コード例 #7
0
ファイル: simplex.c プロジェクト: marso329/courses
void convert_geq_to_leq(problem* prob, work_set* virtual_vars, matrix** Fr, matrix** gr){
  /* Convert >= to <= */
  if (prob->inequality_count > 0){
    *Fr = matrix_copy(prob->F);
    multiply_matrix_with_scalar(-1, *Fr);
    *gr = matrix_copy(prob->g);
    multiply_matrix_with_scalar(-1, *gr);

    /* Find last virtual variable */
    size_t r;
    for (r = 1; r <= prob->inequality_count; r++){
      if (compare_elements(get_value_without_check(r, 1, *gr), 0) == -1){
        work_set_append(virtual_vars, r+prob->equality_count);
      }
    }
  }
}
コード例 #8
0
ファイル: maketoeplitzCIJ.cpp プロジェクト: igormis/bct-cpp
/*
 * Generates a random directed binary graph with a Toeplitz organization.
 */
MATRIX_T* BCT_NAMESPACE::maketoeplitzCIJ(int N, int K, FP_T s) {
	
	// profile = normpdf([1:N-1],0.5,s);
	VECTOR_T* indices = sequence(1, N - 1);
	VECTOR_T* profile = normpdf(indices, 0.5, s);
	VECTOR_ID(free)(indices);
	
	// template = toeplitz([0 profile],[0 profile]);
	VECTOR_T* temp = concatenate(0.0, profile);
	VECTOR_ID(free)(profile);
	profile = temp;
	MATRIX_T* _template = toeplitz(profile, profile);
	VECTOR_ID(free)(profile);
	
	// template = template.*(K./sum(sum(template)))
	VECTOR_T* sum__template = sum(_template);
	FP_T sum_sum__template = sum(sum__template);
	VECTOR_ID(free)(sum__template);
	MATRIX_ID(scale)(_template, (FP_T)K / sum_sum__template);
	
	// CIJ = zeros(N);
	MATRIX_T* CIJ = zeros(N);
	
	// while ((sum(sum(CIJ)) ~= K))
	VECTOR_T* sum_CIJ = sum(CIJ);
	FP_T sum_sum_CIJ = sum(sum_CIJ);
	VECTOR_ID(free)(sum_CIJ);
	while ((int)sum_sum_CIJ != K) {
		
		// CIJ = (rand(N)<template);
		MATRIX_T* rand_N = rand(N);
		MATRIX_ID(free)(CIJ);
		CIJ = compare_elements(rand_N, fp_less, _template);
		MATRIX_ID(free)(rand_N);
		
		sum_CIJ = sum(CIJ);
		sum_sum_CIJ = sum(sum_CIJ);
		VECTOR_ID(free)(sum_CIJ);
	}
	
	MATRIX_ID(free)(_template);
	return CIJ;
}
コード例 #9
0
ファイル: motif3funct_wei.cpp プロジェクト: igormis/bct-cpp
/*
 * Counts occurrences of three-node functional motifs in a weighted graph.
 * Returns intensity and (optionally) coherence and motif counts.
 */
MATRIX_T* BCT_NAMESPACE::motif3funct_wei(const MATRIX_T* W, MATRIX_T** Q, MATRIX_T** F) {
	if (safe_mode) check_status(W, SQUARE | WEIGHTED, "motif3funct_wei");
	
	// load motif34lib M3 M3n ID3 N3
	VECTOR_T* ID3;
	VECTOR_T* N3;
	MATRIX_T* M3 = motif3generate(&ID3, &N3);
	
	// n=length(W);
	int n = length(W);
	
	// I=zeros(13,n);
	MATRIX_T* I = zeros(13, n);
	
	// Q=zeros(13,n);
	if (Q != NULL) {
		*Q = zeros(13, n);
	}
	
	// F=zeros(13,n);
	if (F != NULL) {
		*F = zeros(13, n);
	}
	
	// A=1*(W~=0);
	MATRIX_T* A = compare_elements(W, fp_not_equal, 0.0);
	
	// As=A|A.';
	MATRIX_T* A_transpose = MATRIX_ID(alloc)(A->size2, A->size1);
	MATRIX_ID(transpose_memcpy)(A_transpose, A);
	MATRIX_T* As = logical_or(A, A_transpose);
	MATRIX_ID(free)(A_transpose);
	
	// for u=1:n-2
	for (int u = 0; u < n - 2; u++) {
		
		// V1=[false(1,u) As(u,u+1:n)];
		VECTOR_T* V1 = VECTOR_ID(alloc)(n);
		MATRIX_ID(get_row)(V1, As, u);
		for (int i = 0; i <= u; i++) {
			VECTOR_ID(set)(V1, i, 0.0);
		}
		
		// for v1=find(V1)
		VECTOR_T* find_V1 = find(V1);
		if (find_V1 != NULL) {
			for (int i_find_V1 = 0; i_find_V1 < (int)find_V1->size; i_find_V1++) {
				int v1 = (int)VECTOR_ID(get)(find_V1, i_find_V1);
				
				// V2=[false(1,u) As(v1,u+1:n)];
				VECTOR_T* V2 = VECTOR_ID(alloc)(n);
				MATRIX_ID(get_row)(V2, As, v1);
				for (int i = 0; i <= u; i++) {
					VECTOR_ID(set)(V2, i, 0.0);
				}
				
				// V2(V1)=0;
				logical_index_assign(V2, V1, 0.0);
				
				// V2=([false(1,v1) As(u,v1+1:n)])|V2;
				VECTOR_T* V2_1 = VECTOR_ID(alloc)(n);
				MATRIX_ID(get_row)(V2_1, As, u);
				for (int i = 0; i <= v1; i++) {
					VECTOR_ID(set)(V2_1, i, 0.0);
				}
				VECTOR_T* V2_2 = V2;
				V2 = logical_or(V2_1, V2_2);
				VECTOR_ID(free)(V2_1);
				VECTOR_ID(free)(V2_2);
				
				// for v2=find(V2)
				VECTOR_T* find_V2 = find(V2);
				if (find_V2 != NULL) {
					for (int i_find_V2 = 0; i_find_V2 < (int)find_V2->size; i_find_V2++) {
						int v2 = (int)VECTOR_ID(get)(find_V2, i_find_V2);
						
						// w=[W(v1,u) W(v2,u) W(u,v1) W(v2,v1) W(u,v2) W(v1,v2)];
						int WA_rows[] = { v1, v2, u, v2, u, v1 };
						int WA_cols[] = { u, u, v1, v1, v2, v2 };
						VECTOR_T* w = VECTOR_ID(alloc)(6);
						for (int i = 0; i < 6; i++) {
							VECTOR_ID(set)(w, i, MATRIX_ID(get)(W, WA_rows[i], WA_cols[i]));
						}
						
						// a=[A(v1,u);A(v2,u);A(u,v1);A(v2,v1);A(u,v2);A(v1,v2)];
						MATRIX_T* a = MATRIX_ID(alloc)(6, 1);
						for (int i = 0; i < 6; i++) {
							MATRIX_ID(set)(a, i, 0, MATRIX_ID(get)(A, WA_rows[i], WA_cols[i]));
						}
						
						// ind=(M3*a)==N3;
						MATRIX_T* M3_mul_a_m = mul(M3, a);
						MATRIX_ID(free)(a);
						VECTOR_T* M3_mul_a = to_vector(M3_mul_a_m);
						MATRIX_ID(free)(M3_mul_a_m);
						VECTOR_T* ind = compare_elements(M3_mul_a, fp_equal, N3);
						VECTOR_ID(free)(M3_mul_a);
						
						// m=sum(ind);
						int m = (int)sum(ind);
						if (m > 0) {
							
							// M=M3(ind,:).*repmat(w,m,1);
							VECTOR_T* M3_cols = sequence(0, M3->size2 - 1);
							MATRIX_T* M = log_ord_index(M3, ind, M3_cols);
							VECTOR_ID(free)(M3_cols);
							for (int i = 0; i < (int)M->size1; i++) {
								VECTOR_ID(view) M_row_i = MATRIX_ID(row)(M, i);
								VECTOR_ID(mul)(&M_row_i.vector, w);
							}
							
							// id=ID3(ind);
							VECTOR_T* id = logical_index(ID3, ind);
							VECTOR_ID(add_constant)(id, -1.0);
							
							// l=N3(ind);
							VECTOR_T* l = logical_index(N3, ind);
							
							// x=sum(M,2)./l;
							VECTOR_T* x = sum(M, 2);
							VECTOR_ID(div)(x, l);
							
							// M(M==0)=1;
							MATRIX_T* M_eq_0 = compare_elements(M, fp_equal, 0.0);
							logical_index_assign(M, M_eq_0, 1.0);
							MATRIX_ID(free)(M_eq_0);
							
							// i=prod(M,2).^(1./l);
							VECTOR_T* prod_M = prod(M, 2);
							MATRIX_ID(free)(M);
							VECTOR_T* l_pow_neg_1 = pow_elements(l, -1.0);
							VECTOR_ID(free)(l);
							VECTOR_T* i = pow_elements(prod_M, l_pow_neg_1);
							VECTOR_ID(free)(prod_M);
							VECTOR_ID(free)(l_pow_neg_1);
							
							// q = i./x;
							VECTOR_T* q = copy(i);
							VECTOR_ID(div)(q, x);
							VECTOR_ID(free)(x);
							
							// [idu j]=unique(id);
							VECTOR_T* j;
							VECTOR_T* idu = unique(id, "last", &j);
							VECTOR_ID(free)(id);
							
							// j=[0;j];
							VECTOR_T* temp = VECTOR_ID(alloc)(j->size + 1);
							VECTOR_ID(set)(temp, 0, -1.0);
							VECTOR_ID(view) temp_subv = VECTOR_ID(subvector)(temp, 1, j->size);
							VECTOR_ID(memcpy)(&temp_subv.vector, j);
							VECTOR_ID(free)(j);
							j = temp;
							
							// mu=length(idu);
							int mu = length(idu);
							
							// i2=zeros(mu,1);
							VECTOR_T* i2 = zeros_vector(mu);
							
							// q2=i2; f2=i2;
							VECTOR_T* q2 = copy(i2);
							VECTOR_T* f2 = copy(i2);
							
							// for h=1:mu
							for (int h = 0; h < mu; h++) {
								
								// i2(h)=sum(i(j(h)+1:j(h+1)));
								int j_h = (int)VECTOR_ID(get)(j, h);
								int j_h_add_1 = (int)VECTOR_ID(get)(j, h + 1);
								VECTOR_T* iq_indices = sequence(j_h + 1, j_h_add_1);
								VECTOR_T* i_idx = ordinal_index(i, iq_indices);
								VECTOR_ID(set)(i2, h, sum(i_idx));
								VECTOR_ID(free)(i_idx);
								
								// q2(h)=sum(q(j(h)+1:j(h+1)));
								VECTOR_T* q_idx = ordinal_index(q, iq_indices);
								VECTOR_ID(free)(iq_indices);
								VECTOR_ID(set)(q2, h, sum(q_idx));
								VECTOR_ID(free)(q_idx);
								
								// f2(h)=j(h+1)-j(h);
								VECTOR_ID(set)(f2, h, (FP_T)(j_h_add_1 - j_h));
							}
							VECTOR_ID(free)(i);
							VECTOR_ID(free)(q);
							VECTOR_ID(free)(j);
							
							// I(idu,[u v1 v2])=I(idu,[u v1 v2])+[i2 i2 i2];
							// Q(idu,[u v1 v2])=Q(idu,[u v1 v2])+[q2 q2 q2];
							// F(idu,[u v1 v2])=F(idu,[u v1 v2])+[f2 f2 f2];
							FP_T IQF_cols[] = { (FP_T)u, (FP_T)v1, (FP_T)v2 };
							VECTOR_ID(view) IQF_cols_vv = VECTOR_ID(view_array)(IQF_cols, 3);
							MATRIX_T* I_idx = ordinal_index(I, idu, &IQF_cols_vv.vector);
							MATRIX_T* Q_idx = NULL;
							MATRIX_T* F_idx = NULL;
							if (Q != NULL) {
								Q_idx = ordinal_index(*Q, idu, &IQF_cols_vv.vector);
							}
							if (F != NULL) {
								F_idx = ordinal_index(*F, idu, &IQF_cols_vv.vector);
							}
							for (int j = 0; j < 3; j++) {
								VECTOR_ID(view) I_idx_col_j = MATRIX_ID(column)(I_idx, j);
								VECTOR_ID(add)(&I_idx_col_j.vector, i2);
								if (Q != NULL) {
									VECTOR_ID(view) Q_idx_col_j = MATRIX_ID(column)(Q_idx, j);
									VECTOR_ID(add)(&Q_idx_col_j.vector, q2);
								}
								if (F != NULL) {
									VECTOR_ID(view) F_idx_col_j = MATRIX_ID(column)(F_idx, j);
									VECTOR_ID(add)(&F_idx_col_j.vector, f2);
								}
							}
							VECTOR_ID(free)(i2);
							VECTOR_ID(free)(q2);
							VECTOR_ID(free)(f2);
							ordinal_index_assign(I, idu, &IQF_cols_vv.vector, I_idx);
							MATRIX_ID(free)(I_idx);
							if (Q != NULL) {
								ordinal_index_assign(*Q, idu, &IQF_cols_vv.vector, Q_idx);
								MATRIX_ID(free)(Q_idx);
							}
							if (F != NULL) {
								ordinal_index_assign(*F, idu, &IQF_cols_vv.vector, F_idx);
								MATRIX_ID(free)(F_idx);
							}
							VECTOR_ID(free)(idu);
						}
						
						VECTOR_ID(free)(w);
						VECTOR_ID(free)(ind);
					}
					
					VECTOR_ID(free)(find_V2);
				}
				
				VECTOR_ID(free)(V2);
			}
			
			VECTOR_ID(free)(find_V1);
		}
		
		VECTOR_ID(free)(V1);
	}
	
	VECTOR_ID(free)(ID3);
	VECTOR_ID(free)(N3);
	MATRIX_ID(free)(M3);
	MATRIX_ID(free)(A);
	MATRIX_ID(free)(As);
	return I;
}
コード例 #10
0
ファイル: motif4funct_bin.cpp プロジェクト: igormis/bct-cpp
/*
 * Counts occurrences of four-node functional motifs in a binary graph.
 */
VECTOR_T* BCT_NAMESPACE::motif4funct_bin(const MATRIX_T* W, MATRIX_T** F) {
	if (safe_mode) check_status(W, SQUARE | BINARY, "motif4funct_bin");
	
	// load motif34lib M4 ID4 N4
	VECTOR_T* ID4;
	VECTOR_T* N4;
	MATRIX_T* M4 = motif4generate(&ID4, &N4);
	
	// n=length(W);
	int n = length(W);
	
	// f=zeros(199,1);
	VECTOR_T* f = zeros_vector(199);
	
	// F=zeros(199,n);
	if (F != NULL) {
		*F = zeros(199, n);
	}
	
	// A=1*(W~=0);
	MATRIX_T* A = compare_elements(W, fp_not_equal, 0.0);
	
	// As=A|A.';
	MATRIX_T* A_transpose = MATRIX_ID(alloc)(A->size2, A->size1);
	MATRIX_ID(transpose_memcpy)(A_transpose, A);
	MATRIX_T* As = logical_or(A, A_transpose);
	MATRIX_ID(free)(A_transpose);
	
	// for u=1:n-3
	for (int u = 0; u < n - 3; u++) {
		
		// V1=[false(1,u) As(u,u+1:n)];
		VECTOR_T* V1 = VECTOR_ID(alloc)(n);
		MATRIX_ID(get_row)(V1, As, u);
		for (int i = 0; i <= u; i++) {
			VECTOR_ID(set)(V1, i, 0.0);
		}
		
		// for v1=find(V1)
		VECTOR_T* find_V1 = find(V1);
		if (find_V1 != NULL) {
			for (int i_find_V1 = 0; i_find_V1 < (int)find_V1->size; i_find_V1++) {
				int v1 = (int)VECTOR_ID(get)(find_V1, i_find_V1);
				
				// V2=[false(1,u) As(v1,u+1:n)];
				VECTOR_T* V2 = VECTOR_ID(alloc)(n);
				MATRIX_ID(get_row)(V2, As, v1);
				for (int i = 0; i <= u; i++) {
					VECTOR_ID(set)(V2, i, 0.0);
				}
				
				// V2(V1)=0;
				logical_index_assign(V2, V1, 0.0);
				
				// V2=V2|([false(1,v1) As(u,v1+1:n)]);
				VECTOR_T* V2_1 = V2;
				VECTOR_T* V2_2 = VECTOR_ID(alloc)(n);
				MATRIX_ID(get_row)(V2_2, As, u);
				for (int i = 0; i <= v1; i++) {
					VECTOR_ID(set)(V2_2, i, 0.0);
				}
				V2 = logical_or(V2_1, V2_2);
				VECTOR_ID(free)(V2_1);
				VECTOR_ID(free)(V2_2);
				
				// for v2=find(V2)
				VECTOR_T* find_V2 = find(V2);
				if (find_V2 != NULL) {
					for (int i_find_V2 = 0; i_find_V2 < (int)find_V2->size; i_find_V2++) {
						int v2 = (int)VECTOR_ID(get)(find_V2, i_find_V2);
						
						// vz=max(v1,v2);
						int vz = (v1 > v2) ? v1 : v2;
						
						// V3=([false(1,u) As(v2,u+1:n)]);
						VECTOR_T* V3 = VECTOR_ID(alloc)(n);
						MATRIX_ID(get_row)(V3, As, v2);
						for (int i = 0; i <= u; i++) {
							VECTOR_ID(set)(V3, i, 0.0);
						}
						
						// V3(V2)=0;
						logical_index_assign(V3, V2, 0.0);
						
						// V3=V3|([false(1,v2) As(v1,v2+1:n)]);
						VECTOR_T* V3_1 = V3;
						VECTOR_T* V3_2 = VECTOR_ID(alloc)(n);
						MATRIX_ID(get_row)(V3_2, As, v1);
						for (int i = 0; i <= v2; i++) {
							VECTOR_ID(set)(V3_2, i, 0.0);
						}
						V3 = logical_or(V3_1, V3_2);
						VECTOR_ID(free)(V3_1);
						VECTOR_ID(free)(V3_2);
						
						// V3(V1)=0;
						logical_index_assign(V3, V1, 0.0);
						
						// V3=V3|([false(1,vz) As(u,vz+1:n)]);
						V3_1 = V3;
						V3_2 = VECTOR_ID(alloc)(n);
						MATRIX_ID(get_row)(V3_2, As, u);
						for (int i = 0; i <= vz; i++) {
							VECTOR_ID(set)(V3_2, i, 0.0);
						}
						V3 = logical_or(V3_1, V3_2);
						VECTOR_ID(free)(V3_1);
						VECTOR_ID(free)(V3_2);
						
						// for v3=find(V3)
						VECTOR_T* find_V3 = find(V3);
						if (find_V3 != NULL ) {
							for (int i_find_V3 = 0; i_find_V3 < (int)find_V3->size; i_find_V3++) {
								int v3 = (int)VECTOR_ID(get)(find_V3, i_find_V3);
								
								// a=[A(v1,u);A(v2,u);A(v3,u);A(u,v1);A(v2,v1);A(v3,v1);A(u,v2);A(v1,v2);A(v3,v2);A(u,v3);A(v1,v3);A(v2,v3)];
								int A_rows[] = { v1, v2, v3, u, v2, v3, u, v1, v3, u, v1, v2 };
								int A_cols[] = { u, u, u, v1, v1, v1, v2, v2, v2, v3, v3, v3 };
								MATRIX_T* a = MATRIX_ID(alloc)(12, 1);
								for (int i = 0; i < 12; i++) {
									MATRIX_ID(set)(a, i, 0, MATRIX_ID(get)(A, A_rows[i], A_cols[i]));
								}
								
								// ind=(M4*a)==N4;
								MATRIX_T* M4_mul_a_m = mul(M4, a);
								MATRIX_ID(free)(a);
								VECTOR_T* M4_mul_a = to_vector(M4_mul_a_m);
								MATRIX_ID(free)(M4_mul_a_m);
								VECTOR_T* ind = compare_elements(M4_mul_a, fp_equal, N4);
								VECTOR_ID(free)(M4_mul_a);
								
								// id=ID4(ind);
								VECTOR_T* id = logical_index(ID4, ind);
								VECTOR_ID(free)(ind);
								if (id != NULL) {
									VECTOR_ID(add_constant)(id, -1.0);
								
									// [idu j]=unique(id);
									VECTOR_T* j;
									VECTOR_T* idu = unique(id, "last", &j);
									VECTOR_ID(free)(id);
									
									// j=[0;j];
									VECTOR_T* temp = VECTOR_ID(alloc)(j->size + 1);
									VECTOR_ID(set)(temp, 0, -1.0);
									VECTOR_ID(view) temp_subv = VECTOR_ID(subvector)(temp, 1, j->size);
									VECTOR_ID(memcpy)(&temp_subv.vector, j);
									VECTOR_ID(free)(j);
									j = temp;
									
									// mu=length(idu);
									int mu = length(idu);
									
									// f2=zeros(mu,1);
									VECTOR_T* f2 = zeros_vector(mu);
									
									// for h=1:mu
									for (int h = 0; h < mu; h++) {
										
										// f2(h)=j(h+1)-j(h);
										FP_T j_h_add_1 = VECTOR_ID(get)(j, h + 1);
										FP_T j_h = VECTOR_ID(get)(j, h);
										VECTOR_ID(set)(f2, h, j_h_add_1 - j_h);
									}
									VECTOR_ID(free)(j);
									
									// f(idu)=f(idu)+f2;
									VECTOR_T* f_idu_add_f2 = ordinal_index(f, idu);
									VECTOR_ID(add)(f_idu_add_f2, f2);
									ordinal_index_assign(f, idu, f_idu_add_f2);
									VECTOR_ID(free)(f_idu_add_f2);
									
									// if nargout==2; F(idu,[u v1 v2 v3])=F(idu,[u v1 v2 v3])+[f2 f2 f2 f2]; end
									if (F != NULL) {
										FP_T F_cols[] = { (FP_T)u, (FP_T)v1, (FP_T)v2, (FP_T)v3 };
										VECTOR_ID(view) F_cols_vv = VECTOR_ID(view_array)(F_cols, 4);
										MATRIX_T* F_idx = ordinal_index(*F, idu, &F_cols_vv.vector);
										for (int i = 0; i < 4; i++) {
											VECTOR_ID(view) F_idx_col_i = MATRIX_ID(column)(F_idx, i);
											VECTOR_ID(add)(&F_idx_col_i.vector, f2);
										}
										ordinal_index_assign(*F, idu, &F_cols_vv.vector, F_idx);
										MATRIX_ID(free)(F_idx);
									}
									
									VECTOR_ID(free)(idu);
									VECTOR_ID(free)(f2);
								}
							}
							
							VECTOR_ID(free)(find_V3);
						}
						
						VECTOR_ID(free)(V3);
					}
					
					VECTOR_ID(free)(find_V2);
				}
				
				VECTOR_ID(free)(V2);
			}
			
			VECTOR_ID(free)(find_V1);
		}
		
		VECTOR_ID(free)(V1);
	}
	
	VECTOR_ID(free)(ID4);
	VECTOR_ID(free)(N4);
	MATRIX_ID(free)(M4);
	MATRIX_ID(free)(A);
	MATRIX_ID(free)(As);
	return f;
}
コード例 #11
0
ファイル: simplex.c プロジェクト: marso329/courses
bool simplex_min(problem* prob, matrix* tableau, work_set* basis){
  int column, row;
  value cur, last;
  bool error = false;

  /* Set z0 to 0 */
  size_t r;
  for (r = 1; r <= prob->variable_count; r++){
    insert_value_without_check(0, r, 1, prob->z0);
  }

  /* Solve */ 
  while (!is_neg_tableau_row(tableau->rows, tableau)){
    column = -1;
    row = -1;
    cur = 0;
    last = 0;

    /* Find most positive element in objective */
    size_t c;
    for (c = 1; c <= tableau->columns-1; c++){
      cur = get_value_without_check(tableau->rows, c, tableau);
      if (compare_elements(cur,last) == 1){        
        column = c;
        last = cur;
      }
    }

    /* Should not be able to happen */
    if (column == -1){
      error = true;
      break;
    }

    /* Run min test on choosen column */
    row = min_test(column, tableau);

    /* Infeasible problem */
    if (row == -1){
      error = true;
      break;
    }   

    /* Change basis */
    basis->data[row-1] = column;

    /* Get a 1 at choosen position */
    value div = get_value_without_check(row, column, tableau);
    divide_row_with_scalar(div, row, tableau);

    /* Eliminate other values in the column */
    value scal;
    matrix* pivot_row;
    matrix* old_row;
    matrix* new_row;

    for (r = 1; r <= tableau->rows; r++){
      if ((int)r == row){
        continue;
      }
      scal = -get_value_without_check(r, column, tableau);
      old_row = get_row_vector_with_return(r, tableau);

      pivot_row = get_row_vector_with_return(row, tableau);
      multiply_matrix_with_scalar(scal, pivot_row);

      new_row = add_matrices_with_return(pivot_row, old_row);

      insert_row_vector(r, new_row, tableau);

      free_matrix(pivot_row);
      free_matrix(old_row);
      free_matrix(new_row);
    }    
  }

  return error;
}
コード例 #12
0
ファイル: vertexdeclaration.c プロジェクト: devyn/wine
/* Check whether a declaration converted from FVF is shared.
 * Check whether refcounts behave as expected */
static void test_fvf_decl_management(
    IDirect3DDevice9* device) {

    HRESULT hr;
    IDirect3DVertexDeclaration9* result_decl1 = NULL;
    IDirect3DVertexDeclaration9* result_decl2 = NULL;
    IDirect3DVertexDeclaration9* result_decl3 = NULL;
    IDirect3DVertexDeclaration9* result_decl4 = NULL;
    int ref1, ref2, ref3, ref4;

    DWORD test_fvf1 = D3DFVF_XYZRHW;
    DWORD test_fvf2 = D3DFVF_NORMAL;
    CONST D3DVERTEXELEMENT9 test_elements1[] =
        { { 0, 0, D3DDECLTYPE_FLOAT4, 0, D3DDECLUSAGE_POSITIONT, 0 }, D3DDECL_END() };
    CONST D3DVERTEXELEMENT9 test_elements2[] =
        { { 0, 0, D3DDECLTYPE_FLOAT3, 0, D3DDECLUSAGE_NORMAL, 0 }, D3DDECL_END() };

    /* Clear down any current vertex declaration */
    hr = IDirect3DDevice9_SetVertexDeclaration ( device, NULL );
    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Conversion */
    hr = IDirect3DDevice9_SetFVF( device, test_fvf1);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Get converted decl (#1) */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl1);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Get converted decl again (#2) */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl2);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* Conversion */
    hr = IDirect3DDevice9_SetFVF( device, test_fvf2);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* The contents should correspond to the first conversion */
    VDECL_CHECK(compare_elements(result_decl1, test_elements1));

    /* Get converted decl (#3) */
    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl3);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    /* The object should be the same */
    ok (result_decl1 == result_decl2, "Declaration object changes on the second Get() call\n");
    ok (result_decl2 != result_decl3, "Declaration object did not change during conversion\n");

    /* The contents should correspond to the second conversion */
    VDECL_CHECK(compare_elements(result_decl3, test_elements2));
    /* Re-Check if the first decl was overwritten by the new Get() */
    VDECL_CHECK(compare_elements(result_decl1, test_elements1));

    hr = IDirect3DDevice9_SetFVF( device, test_fvf1);
    ok(SUCCEEDED(hr), "SetFVF returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    hr = IDirect3DDevice9_GetVertexDeclaration ( device, &result_decl4);
    ok(SUCCEEDED(hr), "GetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    ok(result_decl4 == result_decl1, "Setting an already used FVF over results in a different vertexdeclaration\n");

    ref1 = get_refcount((IUnknown*) result_decl1);
    ref2 = get_refcount((IUnknown*) result_decl2);
    ref3 = get_refcount((IUnknown*) result_decl3);
    ref4 = get_refcount((IUnknown*) result_decl4);
    ok (ref1 == 3, "Refcount #1 is %d, expected 3\n", ref1);
    ok (ref2 == 3, "Refcount #2 is %d, expected 3\n", ref2);
    ok (ref3 == 1, "Refcount #3 is %d, expected 1\n", ref3);
    ok (ref4 == 3, "Refcount #4 is %d, expected 3\n", ref4);

    /* Clear down any current vertex declaration */
    hr = IDirect3DDevice9_SetVertexDeclaration ( device, NULL );
    ok (SUCCEEDED(hr), "SetVertexDeclaration returned %#x, expected %#x\n", hr, D3D_OK);
    if (FAILED(hr)) return;

    IDirect3DVertexDeclaration9_Release(result_decl1);
    IDirect3DVertexDeclaration9_Release(result_decl2);
    IDirect3DVertexDeclaration9_Release(result_decl3);
    IDirect3DVertexDeclaration9_Release(result_decl4);

    return;
}
コード例 #13
0
ファイル: betweenness_wei.cpp プロジェクト: igormis/bct-cpp
/*
 * Computes node and edge betweenness for a weighted graph.
 */
MATRIX_T* BCT_NAMESPACE::edge_betweenness_wei(const MATRIX_T* G, VECTOR_T** BC) {
	if (safe_mode) check_status(G, SQUARE | WEIGHTED, "edge_betweenness_wei");
	
	// n=length(G);
	int n = length(G);
	
	// BC=zeros(n,1);
	if (BC != NULL) {
		*BC = zeros_vector(n);
	}
	
	// EBC=zeros(n);
	MATRIX_T* EBC = zeros(n);
	
	// for u=1:n
	for (int u = 0; u < n; u++) {
		
		// D=inf(1,n); D(u) = 0;
		VECTOR_T* D = VECTOR_ID(alloc)(n);
		VECTOR_ID(set_all)(D, GSL_POSINF);
		VECTOR_ID(set)(D, u, 0.0);
		
		// NP=zeros(1,n); NP(u)=1;
		VECTOR_T* NP = zeros_vector(n);
		VECTOR_ID(set)(NP, u, 1.0);
		
		// S=true(1,n);
		VECTOR_T* S = VECTOR_ID(alloc)(n);
		VECTOR_ID(set_all)(S, 1.0);
		
		// P=false(n);
		MATRIX_T* P = MATRIX_ID(calloc)(n, n);
		
		// Q=zeros(1,n); q=n;
		VECTOR_T* Q = zeros_vector(n);
		int q = n - 1;
		
		// G1=G;
		MATRIX_T* G1 = copy(G);
		
		// V=u;
		VECTOR_T* V = VECTOR_ID(alloc)(1);
		VECTOR_ID(set)(V, 0, (FP_T)u);
		
		// while 1
		while (true) {
			
			// S(V)=0;
			ordinal_index_assign(S, V, 0.0);
			
			// G1(:,V)=0;
			VECTOR_T* G1_rows = sequence(0, G1->size1 - 1);
			ordinal_index_assign(G1, G1_rows, V, 0.0);
			VECTOR_ID(free)(G1_rows);
			
			// for v=V
			for (int i_V = 0; i_V < (int)V->size; i_V++) {
				int v = (int)VECTOR_ID(get)(V, i_V);
				
				// Q(q)=v; q=q-1;
				VECTOR_ID(set)(Q, q--, (FP_T)v);
				
				// W=find(G1(v,:));
				VECTOR_ID(view) G1_row_v = MATRIX_ID(row)(G1, v);
				VECTOR_T* W = find(&G1_row_v.vector);
				if (W != NULL) {
					
					// for w=W
					for (int i_W = 0; i_W < (int)W->size; i_W++) {
						int w = (int)VECTOR_ID(get)(W, i_W);
						
						// Duw=D(v)+G1(v,w);
						FP_T Duw = VECTOR_ID(get)(D, v) + MATRIX_ID(get)(G1, v, w);
						
						// if Duw<D(w)
						if (Duw < VECTOR_ID(get)(D, w)) {
							
							// D(w)=Duw;
							VECTOR_ID(set)(D, w, Duw);
							
							// NP(w)=NP(v);
							VECTOR_ID(set)(NP, w, VECTOR_ID(get)(NP, v));
							
							// P(w,:)=0;
							VECTOR_ID(view) P_row_w = MATRIX_ID(row)(P, w);
							VECTOR_ID(set_zero)(&P_row_w.vector);
							
							// P(w,v)=1;
							MATRIX_ID(set)(P, w, v, 1.0);
							
							// elseif Duw==D(w)
						} else if (fp_equal(Duw, VECTOR_ID(get)(D, w))) {
							
							// NP(w)=NP(w)+NP(v);
							VECTOR_ID(set)(NP, w, VECTOR_ID(get)(NP, w) + VECTOR_ID(get)(NP, v));
							
							// P(w,v)=1;
							MATRIX_ID(set)(P, w, v, 1.0);
						}
					}
					VECTOR_ID(free)(W);
				}
			}
			
			// if isempty(minD), break
			if (nnz(S) == 0) {
				break;
			} else {
				
				// minD=min(D(S))
				VECTOR_T* D_S = logical_index(D, S);
				FP_T minD = VECTOR_ID(min)(D_S);
				VECTOR_ID(free)(D_S);
				
				// elseif isinf(minD),
				if (gsl_isinf(minD) == 1) {
					
					// Q(1:q)=find(isinf(D)); break
					VECTOR_T* isinf_D = compare_elements(D, fp_equal, GSL_POSINF);
					VECTOR_T* find_isinf_D = find(isinf_D);
					VECTOR_ID(free)(isinf_D);
					VECTOR_ID(view) Q_subv = VECTOR_ID(subvector)(Q, 0, q + 1);
					VECTOR_ID(memcpy)(&Q_subv.vector, find_isinf_D);
					VECTOR_ID(free)(find_isinf_D);
					break;
				}
				
				// V=find(D==minD);
				VECTOR_ID(free)(V);
				VECTOR_T* D_eq_minD = compare_elements(D, fp_equal, minD);
				V = find(D_eq_minD);
				VECTOR_ID(free)(D_eq_minD);
			}
		}
		
		VECTOR_ID(free)(D);
		VECTOR_ID(free)(S);
		MATRIX_ID(free)(G1);
		VECTOR_ID(free)(V);
		
		// DP=zeros(n,1);
		VECTOR_T* DP = zeros_vector(n);
		
		// for w=Q(1:n-1);
		for (int i_Q = 0; i_Q < n - 1; i_Q++) {
			int w = (int)VECTOR_ID(get)(Q, i_Q);
			
			// BC(w)=BC(w)+DP(w)
			if (BC != NULL) {
				VECTOR_ID(set)(*BC, w, VECTOR_ID(get)(*BC, w) + VECTOR_ID(get)(DP, w));
			}
			
			// for v=find(P(w,:))
			VECTOR_ID(view) P_row_w = MATRIX_ID(row)(P, w);
			VECTOR_T* find_P_row_w = find(&P_row_w.vector);
			if (find_P_row_w != NULL) {
				for (int i_find_P_row_w = 0; i_find_P_row_w < (int)find_P_row_w->size; i_find_P_row_w++) {
					int v = (int)VECTOR_ID(get)(find_P_row_w, i_find_P_row_w);
					
					// DPvw=(1+DP(w)).*NP(v)./NP(w);
					FP_T DP_w = VECTOR_ID(get)(DP, w);
					FP_T NP_v = VECTOR_ID(get)(NP, v);
					FP_T NP_w = VECTOR_ID(get)(NP, w);
					FP_T DPvw = (1 + DP_w) * NP_v / NP_w;
					
					// DP(v)=DP(v)+DPvw;
					VECTOR_ID(set)(DP, v, VECTOR_ID(get)(DP, v) + DPvw);
					
					// EBC(v,w)=EBC(v,w)+DPvw;
					MATRIX_ID(set)(EBC, v, w, MATRIX_ID(get)(EBC, v, w) + DPvw);
				}
				VECTOR_ID(free)(find_P_row_w);
			}
		}
		
		VECTOR_ID(free)(NP);
		MATRIX_ID(free)(P);
		VECTOR_ID(free)(Q);
		VECTOR_ID(free)(DP);
	}
	
	return EBC;
}
コード例 #14
0
ファイル: findpaths.cpp プロジェクト: kbxu/bct-cpp
/*
 * Finds paths from a set of source nodes up to a given length.  Note that there
 * is no savepths argument; if all paths are desired, pass a valid pointer as
 * the allpths argument.  There is also no tpath argument as its value may
 * overflow a C++ long.  Since 0 is a valid node index in C++, -1 is used as the
 * "filler" value in allpths rather than 0 as in MATLAB.  Pq (the main return),
 * plq, and util are indexed by path length.  They therefore have (qmax + 1)
 * elements and contain no valid data at index 0.
 */
std::vector<MATRIX_T*> BCT_NAMESPACE::findpaths(const MATRIX_T* CIJ, const VECTOR_T* sources, int qmax, VECTOR_T** plq, int* qstop, MATRIX_T** allpths, MATRIX_T** util) {
    if (safe_mode) check_status(CIJ, SQUARE, "findpaths");

    // CIJ = double(CIJ~=0);
    MATRIX_T* _CIJ = compare_elements(CIJ, fp_not_equal, 0.0);

    // N = size(CIJ,1);
    int N = CIJ->size1;

    // pths = [];
    MATRIX_T* pths = NULL;

    // Pq = zeros(N,N,qmax);
    std::vector<MATRIX_T*> Pq(qmax + 1);
    Pq[0] = NULL;
    for (int i = 1; i <= qmax; i++) {
        Pq[i] = zeros(N, N);
    }

    // util = zeros(N,qmax);
    if (util != NULL) {
        *util = zeros(N, qmax + 1);
    }

    // q = 1;
    int q = 1;

    VECTOR_T* _CIJ_cols = sequence(0, N - 1);
    MATRIX_T* _CIJ_idx = ordinal_index(_CIJ, sources, _CIJ_cols);
    VECTOR_ID(free)(_CIJ_cols);
    MATRIX_T* _CIJ_idx_ij = find_ij(_CIJ_idx);
    MATRIX_ID(free)(_CIJ_idx);
    pths = MATRIX_ID(alloc)(2, _CIJ_idx_ij->size1);
    for (int i = 0; i < (int)_CIJ_idx_ij->size1; i++) {
        int i_row = (int)MATRIX_ID(get)(_CIJ_idx_ij, i, 0);
        int i_start = (int)VECTOR_ID(get)(sources, i_row);
        int i_end = (int)MATRIX_ID(get)(_CIJ_idx_ij, i, 1);
        MATRIX_ID(set)(pths, 0, i, (FP_T)i_start);
        MATRIX_ID(set)(pths, 1, i, (FP_T)i_end);
    }
    MATRIX_ID(free)(_CIJ_idx_ij);

    // util(1:N,q) = util(1:N,q)+hist(reshape(pths,1,size(pths,1)*size(pths,2)),1:N)';
    if (util != NULL) {
        VECTOR_T* reshape_pths = to_vector(pths);
        VECTOR_T* centers = sequence(0, N - 1);
        VECTOR_T* hist_reshape_pths = hist(reshape_pths, centers);
        VECTOR_ID(free)(reshape_pths);
        VECTOR_ID(free)(centers);
        VECTOR_ID(view) util_col_q = MATRIX_ID(column)(*util, q);
        VECTOR_ID(add)(&util_col_q.vector, hist_reshape_pths);
        VECTOR_ID(free)(hist_reshape_pths);
    }

    // for np=1:size(pths,2)
    for (int np = 0; np < (int)pths->size2; np++) {

        // Pq(pths(1,np),pths(q+1,np),q) = Pq(pths(1,np),pths(q+1,np),q) + 1;
        int i = (int)MATRIX_ID(get)(pths, 0, np);
        int j = (int)MATRIX_ID(get)(pths, q, np);
        MATRIX_ID(set)(Pq[q], i, j, MATRIX_ID(get)(Pq[q], i, j) + 1.0);
    }

    // if (savepths==1)
    if (allpths != NULL) {

        // allpths = pths;
        *allpths = copy(pths);
    }

    // for q=2:qmax
    for (q = 2; q <= qmax; q++) {

        // npths = zeros(q+1,len_npths);
        // Handle as a std::vector<VECTOR_T*> rather than preallocating a MATRIX_T*
        std::vector<VECTOR_T*> npths_v;

        // endp = unique(pths(q,:));
        VECTOR_ID(view) pths_row_q_sub_1 = MATRIX_ID(row)(pths, q - 1);
        VECTOR_T* endp = unique(&pths_row_q_sub_1.vector);

        // npthscnt = 0;
        int npthscnt = 0;

        // for ii=1:length(endp)
        for (int ii = 0; ii < length(endp); ii++) {

            // i = endp(ii);
            int i = (int)VECTOR_ID(get)(endp, ii);

            // [pa,pb] = find(pths(q,:) == i);
            VECTOR_T* pths_row_q_sub_1_eq_i = compare_elements(&pths_row_q_sub_1.vector, fp_equal, (FP_T)i);
            VECTOR_T* pb = find(pths_row_q_sub_1_eq_i);
            VECTOR_ID(free)(pths_row_q_sub_1_eq_i);
            if (pb != NULL) {

                // nendp = find(CIJ(i,:)==1);
                VECTOR_ID(const_view) _CIJ_row_i = MATRIX_ID(const_row)(_CIJ, i);
                VECTOR_T* _CIJ_row_i_eq_1 = compare_elements(&_CIJ_row_i.vector, fp_equal, 1.0);
                VECTOR_T* nendp = find(_CIJ_row_i_eq_1);
                VECTOR_ID(free)(_CIJ_row_i_eq_1);

                // if (~isempty(nendp))
                if (nendp != NULL) {

                    // for jj=1:length(nendp)
                    for (int jj = 0; jj < length(nendp); jj++) {

                        // j = nendp(jj);
                        int j = (int)VECTOR_ID(get)(nendp, jj);

                        // pb_temp = pb(sum(j==pths(2:q,pb),1)==0);
                        VECTOR_T* pths_rows = sequence(1, q - 1);
                        MATRIX_T* pths_idx = ordinal_index(pths, pths_rows, pb);
                        VECTOR_ID(free)(pths_rows);
                        MATRIX_T* pths_idx_eq_j = compare_elements(pths_idx, fp_equal, (FP_T)j);
                        MATRIX_ID(free)(pths_idx);
                        VECTOR_T* sum_pths_idx_eq_j = sum(pths_idx_eq_j, 1);
                        MATRIX_ID(free)(pths_idx_eq_j);
                        VECTOR_T* sum_pths_idx_eq_j_eq_0 = compare_elements(sum_pths_idx_eq_j, fp_equal, 0.0);
                        VECTOR_ID(free)(sum_pths_idx_eq_j);
                        VECTOR_T* pb_temp = logical_index(pb, sum_pths_idx_eq_j_eq_0);
                        VECTOR_ID(free)(sum_pths_idx_eq_j_eq_0);
                        if (pb_temp != NULL) {

                            // npths(:,npthscnt+1:npthscnt+length(pb_temp)) = [pths(:,pb_temp)' ones(length(pb_temp),1)*j]';
                            pths_rows = sequence(0, pths->size1 - 1);
                            pths_idx = ordinal_index(pths, pths_rows, pb_temp);
                            VECTOR_ID(free)(pths_rows);
                            MATRIX_T* temp = MATRIX_ID(alloc)(pths_idx->size1 + 1, pths_idx->size2);
                            MATRIX_ID(view) temp_subm = MATRIX_ID(submatrix)(temp, 0, 0, pths_idx->size1, pths_idx->size2);
                            MATRIX_ID(memcpy)(&temp_subm.matrix, pths_idx);
                            MATRIX_ID(free)(pths_idx);
                            pths_idx = temp;
                            VECTOR_T* last_row = VECTOR_ID(alloc)(length(pb_temp));
                            VECTOR_ID(set_all)(last_row, (FP_T)j);
                            MATRIX_ID(set_row)(pths_idx, pths_idx->size1 - 1, last_row);
                            VECTOR_ID(free)(last_row);
                            for (int i = 0; i < length(pb_temp); i++) {
                                npths_v.push_back(zeros_vector(q + 1));
                                VECTOR_ID(view) pths_idx_col_i = MATRIX_ID(column)(pths_idx, i);
                                VECTOR_ID(view) npths_v_i_subv = VECTOR_ID(subvector)(npths_v[npthscnt + i], 0, pths_idx->size1);
                                VECTOR_ID(memcpy)(&npths_v_i_subv.vector, &pths_idx_col_i.vector);
                            }
                            MATRIX_ID(free)(pths_idx);

                            // npthscnt = npthscnt+length(pb_temp);
                            npthscnt += length(pb_temp);

                            // Pq(1:N,j,q) = Pq(1:N,j,q)+(hist(pths(1,pb_temp),1:N))';
                            VECTOR_ID(view) pths_row_0 = MATRIX_ID(row)(pths, 0);
                            VECTOR_T* pths_row_0_idx = ordinal_index(&pths_row_0.vector, pb_temp);
                            VECTOR_ID(free)(pb_temp);
                            VECTOR_T* centers = sequence(0, N - 1);
                            VECTOR_T* hist_pths_idx = hist(pths_row_0_idx, centers);
                            VECTOR_ID(free)(pths_row_0_idx);
                            VECTOR_ID(free)(centers);
                            VECTOR_ID(view) Pq_q_col_j = MATRIX_ID(column)(Pq[q], j);
                            VECTOR_ID(add)(&Pq_q_col_j.vector, hist_pths_idx);
                            VECTOR_ID(free)(hist_pths_idx);
                        }
                    }

                    VECTOR_ID(free)(nendp);
                }

                VECTOR_ID(free)(pb);
            }
        }

        VECTOR_ID(free)(endp);
        MATRIX_T* npths = MATRIX_ID(alloc)(q + 1, npthscnt);
        for (int i = 0; i < npthscnt; i++) {
            MATRIX_ID(set_col)(npths, i, npths_v[i]);
            VECTOR_ID(free)(npths_v[i]);
        }

        // if (savepths==1)
        if (allpths != NULL) {

            // allpths = [allpths; zeros(1,size(allpths,2))];
            // allpths = [allpths npths(:,1:npthscnt)];
            MATRIX_T* temp = MATRIX_ID(alloc)((*allpths)->size1 + 1, (*allpths)->size2 + npthscnt);
            MATRIX_ID(set_all)(temp, -1.0);
            MATRIX_ID(view) temp_subm = MATRIX_ID(submatrix)(temp, 0, 0, (*allpths)->size1, (*allpths)->size2);
            MATRIX_ID(memcpy)(&temp_subm.matrix, *allpths);
            temp_subm = MATRIX_ID(submatrix)(temp, 0, (*allpths)->size2, (*allpths)->size1 + 1, npthscnt);
            MATRIX_ID(view) npths_subm = MATRIX_ID(submatrix)(npths, 0, 0, npths->size1, npthscnt);
            MATRIX_ID(memcpy)(&temp_subm.matrix, &npths_subm.matrix);
            MATRIX_ID(free)(*allpths);
            *allpths = temp;
        }

        // util(1:N,q) = util(1:N,q) + hist(reshape(npths,1,size(npths,1)*size(npths,2)),1:N)' - diag(Pq(:,:,q));
        if (util != NULL) {
            VECTOR_T* reshape_npths = to_vector(npths);
            VECTOR_T* centers = sequence(0, N - 1);
            VECTOR_T* hist_reshape_npths = hist(reshape_npths, centers);
            VECTOR_ID(free)(reshape_npths);
            VECTOR_ID(free)(centers);
            VECTOR_ID(view) util_col_q = MATRIX_ID(column)(*util, q);
            VECTOR_ID(add)(&util_col_q.vector, hist_reshape_npths);
            VECTOR_ID(free)(hist_reshape_npths);
            VECTOR_ID(view) diag_Pq_q = MATRIX_ID(diagonal)(Pq[q]);
            VECTOR_ID(sub)(&util_col_q.vector, &diag_Pq_q.vector);
        }

        // pths = npths(:,npths(1,:)~=npths(q+1,:));
        VECTOR_T* npths_rows = sequence(0, npths->size1 - 1);
        VECTOR_ID(view) npths_row_0 = MATRIX_ID(row)(npths, 0);
        VECTOR_ID(view) npths_row_q = MATRIX_ID(row)(npths, q);
        VECTOR_T* npths_cols = compare_elements(&npths_row_0.vector, fp_not_equal, &npths_row_q.vector);
        MATRIX_ID(free)(pths);
        pths = ord_log_index(npths, npths_rows, npths_cols);
        MATRIX_ID(free)(npths);
        VECTOR_ID(free)(npths_rows);
        VECTOR_ID(free)(npths_cols);

        // if (isempty(pths))
        // ...
        if (pths == NULL) {
            break;
        }
    }

    MATRIX_ID(free)(_CIJ);
    if (pths != NULL) {
        MATRIX_ID(free)(pths);
    }

    // qstop = q;
    if (qstop != NULL) {
        *qstop = (q <= qmax) ? q : qmax;
    }

    // tpath = sum(sum(sum(Pq)));
    // plq = reshape(sum(sum(Pq)),1,qmax)
    if (plq != NULL) {
        *plq = VECTOR_ID(alloc)(qmax + 1);
        VECTOR_ID(set)(*plq, 0, 0.0);
        for (int i = 1; i <= qmax; i++) {
            VECTOR_T* sum_Pq_i = sum(Pq[i]);
            VECTOR_ID(set)(*plq, i, sum(sum_Pq_i));
            VECTOR_ID(free)(sum_Pq_i);
        }
    }

    return Pq;
}