⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eq.c

📁 circuit calculation program
💻 C
字号:
#include <stdlib.h>
#include "eq.h"

typedef struct EQ_list_def {
	EQ_item_t *eq;
	float_t constant;
	struct EQ_list_def *next;
} EQ_list;

static EQ_list *eq_list;

int EQ_start ()
{
	EQ_list *p;	
	
	p = (EQ_list *) malloc (sizeof (EQ_list));
	if (!p) {error (NO_MEM); }
	else {
		p->next = eq_list;
		p->eq = 0;
		p->constant = 0;

		eq_list = p;
	}

	return !!p;
}	
/* add an item to equation: f(X) = Y */
int EQ_add_const (float_t constant)
{
	EQ_list *p = eq_list;
	assert (p);
	
	p->constant -= constant;   /* merge constant item */
}

/* add an item to equation: f(X) = Y */
int EQ_add (float_t constant, EQ_item_t *item)
{
	EQ_list *p = eq_list;
	EQ_item_t *q,*r;
	
	assert (p);
	assert (item->var_index>=0);
	
	p->constant -= constant;   /* merge constant item */
	
	r = NULL;
	q = p->eq;
	while (q && q->var_index < item->var_index) {r=q; q=q->next;}
	
	if ( q && q->var_index == item->var_index ) {
	/* merge items of the same vars */
		q->coef += item->coef;
		EQ_item_free (item);
	} else {
	/* add to the link */
		item->next = q;
		if (r) r->next = item;
		else p->eq = item;
	}
}


int EQ_end ()
{
}

/* keep the eq list in ascending order of lowerest var index */
int EQ_sort ()
{
	EQ_list *p = eq_list,*q,*r;
	
	assert (p);
	assert (p->eq);
	
	r = NULL;
	q = eq_list->next;  /* scan from the second eq */
	while (q) {
		assert (q->eq);
		
		if (q->eq->var_index < p->eq->var_index) {r=q; q=q->next;}
		else break;
	}
	
	if (r) { /* should insert somewhere between r and q */
		eq_list = eq_list->next;  /* remove it first */
		
		r->next = p;
		p->next = q;
	}
}	

int EQ_reset()
{
	EQ_list *p;
	EQ_item_t *q,*r;
	
	while (p = eq_list) {
		r = p->eq;
		
		while (q=r) {r = q->next; EQ_item_free (q);}
		
		eq_list = eq_list->next;
		free (p);
	}
}

int dump_EQ()
{
	EQ_list *p;
	EQ_item_t *q,*r;
	int  i;
	
	i = 0;	
	p = eq_list;
	while (p) {
		q = p->eq;
		
		printf ("\n%f =", - p->constant);
		while (q) {
			printf ("%f x%d +", q->coef, q->var_index );
			q = q->next; 
		}
		
		p = p->next;
		i ++;
	}
	printf ("\nTotalling equations: %d\n",i );
}	

EQ_item_t *EQ_item_alloc()
{
	return (EQ_item_t *) malloc (sizeof (EQ_item_t));
}	

int EQ_item_free (EQ_item_t *q)
{
	free (q);
	return 0;
}	

/* 
 * find the next eq for var reduction
 *
 */
int EQ_find_var()
{
	EQ_list *p,*t,*p_prev,*t_prev;

	int var_index;

	p_prev = eq_list;
	p = eq_list->next;	
	
	t_prev = NULL;
	t = eq_list;
	
	assert (eq_list->eq);
	var_index = eq_list->eq->var_index;

	while (p) {
		assert (p->eq);
		if (p->eq->var_index < var_index 
		    ||(p->eq->var_index == var_index 
		       && fabs (t->eq->coef) < FLOAT_BCEILING 
  		       && fabs (p->eq->coef) > fabs (t->eq->coef)) ) {
  		       	
			var_index = p->eq->var_index;
			t_prev = p_prev;
			t = p;
		}
		p_prev = p;
		p = p->next;
	}
	
	/* 
	 *move the selected t to the to top
	 */
  	if (t != eq_list ){
  		EQ_list *temp;
		/* remove first */	
		temp = t->next;	
		t_prev->next = temp;
		
		/* insert after x_prev */
		t->next = eq_list;	
		eq_list = t;
		
		return 1;
	}	
	
	return 0;
	
}
/*
 * The first eq is mul-ed and added to the rest eq's
 */

int EQ_reduce_var(EQ_list *p)
{
	EQ_list *t;
	EQ_item_t *q,*r,*s,*r_prev;
	int var_index;

	float_t a,b;

        /* if this eq is null, it means this eq is reduntant 
         * we assure that eq is not null by checking it in the caller
         */
	assert (p->eq);

	q = p->eq;
	a = q->coef;
	var_index = q->var_index;
		
	t = p->next;
	/* reduce the first variable in p */
	while (t) {
			assert (t->eq);	

			assert (t!=p);			
			r = t->eq;
			/* because eq list is sorted, so when no var can be
			 * reduced, stop
			 */
			if (r->var_index > var_index ) goto next; 
			
			assert (r->var_index == var_index );
			assert (fabs (a) > FLOAT_BCEILING 
  			        || fabs (r->coef) < fabs (a) );
	
  			/*
  			 * now b is expected to have a normal value
  			 * see EQ_find_var ()
  			 */ 
			b = -r->coef/a;
		
			/* constant item */
			t->constant += p->constant * b;
			
			/* drop r */
			s = r;
			r = t->eq = s->next;
			EQ_item_free (s);
			
			/* then add each item in q to r */
			r_prev = NULL;
			s = q->next;
			while (s) {
				/* items in an eq are in ascending order of var index */
				while ( r && r->var_index < s->var_index ) { r_prev = r; r = r->next; }
				
				if (r && r->var_index == s->var_index) {
					r->coef = r->coef + s->coef*b;
						
						/* don't check whether the coef is near to 0 now*/
				} else { /* add a new item */
					EQ_item_t *n;
					
					n = EQ_item_alloc ();
					if (!n) {
						error (__FILE__,__LINE__,ENO_MEM);
						return ENO_MEM;
					}
						
					n->var_index = s->var_index;
					n->coef = s->coef*b;
					n->next = r;
						
					if (r_prev) r_prev->next = n;
					else t->eq = n;
				}
				
				s = s->next;
			}
next:
			t = t->next;
	}
	
	return 0;
}	

int EQ_resolve ()
{
	EQ_list *p,*q;
	EQ_item_t *r,*s;
	int i;
	/* step 1. reduce vars /	
	 * processed eq are queued to p 
	 */
	p = NULL;	

	while(eq_list) {
		/* check redundant eq */
		if (!eq_list->eq) {
			q = eq_list;
			eq_list = eq_list->next;
			free (q);
			continue;
		}
		
		/*
		 * when eq_list->next, EQ_xx will return directly
		 */
		EQ_find_var ();
		
		if ( EQ_reduce_var (eq_list)) {
			/* failed. */
			return ENO_MEM;	
		}
		
		/* remove the top eq */
		q = eq_list;
		eq_list = eq_list->next;
		/* move the top eq to p */
		q->next = p;
		p = q;		
	}
	/* step 2. calculate vars 
	 *  Now, p is a triangle like:
	 *              A00*x0                 = y0
	 *              A10*x0 +A11*x1         = y1
	 *              A20*x0 +A21*x1 +A32*X2 = y1
	 */
	
	dump_EQ ();	

	i = 0;	
	while (q) {
		int j;
		
		p = q;	
		q = p->next;
		
		assert (p->eq);   /* all redundant eq's have been removed */		
		
		r = p->eq;
		s = r->next;
	
		
		/* bring in all known vars */
		j = 0;
		while (s ) {
			EQ_item_t *temp;
			
			
			p->constant += s->coef * vars[ s->var_index ];
			
			temp = s;
			s = s->next;
			EQ_item_free (temp);
			
			j ++;
		}

		if (j>i) /* there are more than i vars in the first eq*/
			return ENO_SOLUTION;
				
		/* calc next vars */
		vars[ r->var_index ] = -p->constant / r->coef;	
		
		WATCH (	r->var_index );
		WATCHF (	vars[ r->var_index ] );
		
		EQ_item_free (r);				
		i ++;  /* a new vars is known */
		
		free (p);
	}
	eq_list = 0;
}		


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -