Archivo: /home/young/work/cordic/mvr_exhaustive.c Página 1 de 6 -------------- Purpose: Explore Full Angles Space (exhaustive MVR CORDIC) Discussion: Licensing: This code is distributed under the GNU LGPL license. Modified: 2018.10.04 Author: Young Won Lim Parameters: -------------- #include <stdio.h> #include <math.h> #include <stdlib.h> #define N 8 #define R (N/2) --------------------------------------------------------- (2R+1)-ary tree node 1st R choices -a(0), -a(1),..., -a(r-1) 2nd R choices +a(0), +a(1),..., +a(r-1) last choice zero --------------------------------------------------------- typedef struct node { double theta; int depth; int branch; int id; struct node * child[2*r+1]; struct node * parent; nodetype; --------------------------------------------------------- queue node type used for breadth first search traversal --------------------------------------------------------- typedef struct qnode { struct node * node; struct qnode * next; qnodetype; conventional cordic input initial angle : angle[0] ouput residue angles : angle[1].. angle[n] void conventional_cordic(double a[], double angle[]) { int k = 0, uk; printf("* conventional cordic... \n"); for (k=0; k<n; ++k) { uk = (angle[k] >= 0)? +1 : -1;
Archivo: /home/young/work/cordic/mvr_exhaustive.c Página 2 de 6 printf("k=%2d angle[%2d]=%10.7f ", k, k, angle[k]); printf("uk=%+d ", uk); angle[k+1] = angle[k] - uk * a[k]; printf("a[%2d]=%10.7f ", k, a[k]); printf("angle[%2d]=%+10.5e \n", k+1, angle[k+1]); create a node for the angle tree nodetype * create_node() { nodetype * p = (nodetype *) malloc (sizeof(nodetype)); if (p == NULL) { perror("node creation error \n"); exit(1); else { for (i=0; i<2r+1; ++i) child[i] = NULL; child[r] = NULL; return p; create a node for the queue in order to BFS the angle tree qnodetype * create_qnode() { qnodetype * q = (qnodetype *) malloc (sizeof(qnodetype)); if (q == NULL) { perror("qnode creation error \n"); exit(1); else { node = NULL; next = NULL; return q; elem of depth array points to a list of nodes at the same depth qnodetype *larr[n]; void insert_level_list(nodetype *np) { int depth = np->depth; q = create_qnode(); q->node = np; q->next = larr[depth]; larr[depth] = q; void print_level_list(int depth) { q = larr[depth]; while (q) { printf(" %d %f\n", (q->node)->id, (q->node)->theta);
Archivo: /home/young/work/cordic/mvr_exhaustive.c Página 3 de 6 q = q->next; printf("\n"); nodetype * level_list_min_node(int depth) { nodetype *p; double minval = 1e100; double residue; q = larr[depth]; while (q) { residue = fabs((q->node)->theta); if (minval > residue) { minval = residue; p = q->node; q = q->next; printf("%f \n", p->theta); return(p); find min path from root to node qnodetype *minpath; void find_minpath(nodetype *p) { minpath = NULL; while (p) { q = create_qnode(); q->next = minpath; q->node = p; minpath = q; p = p->parent; void list_minpath(double a[]) { int u, i; while (q) { printf("depth=%d ", (q->node)->depth); printf("theta=%f ", (q->node)->theta); q = q->next; if (q == NULL) { printf("\n"); break; printf("branch=%d ", (q->node)->branch); if ((q->node)->branch < R) u = +1; else if ((q->node)->branch < 2*R) u = -1; else if ((q->node)->branch == 2*R) u = 0; printf("u=%d ", u); i = (q->node)->branch % R; printf("a[%d]=%f ", i, a[i]); printf("\n");
Archivo: /home/young/work/cordic/mvr_exhaustive.c Página 4 de 6 create (2R+1) children node to the current node pointed by p void expand_node(double a[], nodetype *p) { nodetype *np; int i; double ntheta, theta; static int id = 1; printf("* expanding a node... \n"); theta = p->theta; if (p->depth == 0) insert_level_list(p); if (p->branch < 0) return; for (i=0; i<2*r+1; ++i) { if (i < R) ntheta = theta + 1 * a[i%r]; else if (i < 2*R) ntheta = theta - 1 * a[i%r]; else if (i == 2*R) ntheta = theta + 0 * a[i%r]; printf("%d %f =(%f %f) \n", i, ntheta, theta, a[i%r]); np = create_node (); p->child[i] = np; np->parent = p; np->theta = ntheta; np->depth = p->depth +1; np->branch = i; np->id = id++; insert_level_list(np); if (ntheta > theta) np->branch = -1; BFS tree traversal to expand all (2R+1) nodes qnodetype *head =NULL; qnodetype *tail =NULL; void enqueue(qnodetype *q) { printf("* enqueue... \n"); if (head == NULL && tail == NULL) head = q; if (tail!= NULL) tail->next = q; tail = q; qnodetype * dequeue() { printf("* dequeue... \n"); static int depth = 0; if (head!= NULL) { q = head; if (head!= tail) head = head->next; else head = tail = NULL; if (depth!= (q->node)->depth) { printf("level %d \n", depth); depth = (q->node)->depth;
Archivo: /home/young/work/cordic/mvr_exhaustive.c Página 5 de 6 return q; else { return NULL; void tree_traverse(double a[], nodetype *p) { qnodetype *q, *nq; int i, k =0; printf("* tree traversing... \n"); q = create_qnode(); q->node = p; enqueue(q); while (head!= NULL) { printf("* node %d to be expanded \n", k); q = dequeue(); k++; if ((q->node)->depth >= N) break; if (q!= NULL) expand_node(a, q->node); for (i=0; i<2*r+1; ++i) { if ((q->node)->theta < ((q->node)->child[i])->theta) continue; if (((q->node)->child[i])->branch <0) continue; nq = create_qnode(); nq->node = (q->node)->child[i]; enqueue(nq); int main(void) { double a[n]; double angle[n+1]; double theta = 0.63761; double theta = 0.27623; double theta; = 4*atan(pow(2,-5)); int i, s; nodetype *p; nodetype *leaf; for (i=0; i<n; ++i) { a[i] = atan(1./pow(2, i)); for (s=2; s<3; ++s) { theta = s * atan(pow(2, -5)); angle[0] = theta; printf("theta= %2d * atan(pow(2,-6) = %10g \n", s, theta); conventional_cordic(a, angle); p = create_node(); p->theta = theta; p->depth = 0;
Archivo: /home/young/work/cordic/mvr_exhaustive.c Página 6 de 6 tree_traverse(a, p); for (i=0; i<n; ++i) { printf("level %d\n", i); print_level_list(i); level_list_min_node(i); leaf = level_list_min_node(n-1); find_minpath(leaf); list_minpath(a);