static void scan_values(sotl_device_t *dev, int nvalues, int offset_in, int offset_out) { int vtc = exec_scan_kernel (dev, &dev->calc_offset_buffer, offset_in, offset_out, nvalues, NULL); if (vtc > 1) { int new_offset_in = offset_out; int new_offset_out = ALRND(16, offset_out + vtc); scan_values (dev, vtc, new_offset_in, new_offset_out); scan_down_step (dev, &dev->calc_offset_buffer, nvalues, offset_in, offset_out); } }
void scan(sotl_device_t *dev, const unsigned begin, const unsigned end) { int offset_in = begin; int offset_out = begin; int nvalues = end - begin; int vtc = exec_scan_kernel(dev, &dev->box_buffer, offset_in, offset_out, nvalues, prof_event_ptr(dev, KERNEL_SCAN)); // Test if we need to execute another scan if (vtc > 1) { int offset_in = begin; int offset_out = ALRND(16, begin + vtc); scan_values(dev, vtc, offset_in, offset_out); scan_down_step(dev, &dev->box_buffer, nvalues, begin, begin); } }
int ss_model::init(OBJECT *parent) { double val[256]; unsigned int n,m; // determine n by scanning the x vector n = scan_values(x,val,sizeof(val)/sizeof(val[0])); if ( n==256 ) exception("no more than 256 states are permitted"); else if ( n==0 ) exception("at least one state must be defined"); else dim.n = n; // save the x vector ss.x = new double[n]; memcpy(ss.x,val,sizeof(double)*n); // scan the Y vector tf.Y = new double[n]; if ( scan_values(Y,tf.Y,n)!=n ) exception("Y does not have the same number of values as x"); // scan the U vector tf.U = new double[n]; if ( scan_values(U,tf.U,n)!=n ) exception("Y does not have the same number of values as x"); // scan the u references input = new gld_property*[dim.n]; if ( scan_references(u,input,n)!=n ) exception("u does not have the same number of references as x has values"); // determine m by scanning the y vector output = new gld_property*[n]; if ( (m=scan_references(y,output,n))!=1 ) exception("y may have only one reference"); dim.m = m; // construct the A matrix unsigned int i, j; ss.A = new double*[n-1]; switch ( form ) { case CF_OCF: for ( i=0 ; i<n-1 ; i++ ) { ss.A[i] = new double[n-1]; memset(ss.A[i],0,sizeof(double)*(n-1)); ss.A[i][0] = -tf.U[i+1]; ss.A[i][i+1] = 1; } break; case CF_CCF: // TODO break; } // construct the B matrix ss.B = new double*[n-1]; switch ( form ) { case CF_OCF: for ( i=0 ; i<n-1 ; i++ ) { ss.B[i] = new double[m]; memset(ss.B[i],0,sizeof(double)*m); for ( j=0 ; j<m ; j++ ) // TODO generalize for MIMO ss.B[i][j] = tf.Y[i+1] - tf.U[i+1]*tf.Y[j]; } break; case CF_CCF: // TODO break; } // construct the C matrix ss.C = new double*[m]; switch ( form ) { case CF_OCF: for ( i=0 ; i<m ; i++ ) { ss.C[i] = new double[n-1]; memset(ss.C[i],0,sizeof(double)*(n-1)); ss.C[i][0] = 1; } break; case CF_CCF: // TODO break; } ss.D = new double*[1]; switch ( form ) { case CF_OCF: ss.D[0] = new double[1]; // TODO generalize for MIMO ss.D[0][0] = tf.Y[0]; case CF_CCF: // TODO break; } // link control vector ss.u = new double*[n]; for ( i=0 ; i<n ; i++ ) ss.u[i] = (double*)input[i]->get_addr(); // link observation vector ss.y = new double*[m]; for ( i=0 ; i<m ; i++ ) ss.y[i] = (double*)output[i]->get_addr(); // create xdot ss.xdot = new double[n]; memset(ss.xdot,0,sizeof(ss.xdot)); // update H string (just descriptive) int len=1; H[0]='('; for ( i=0 ; i<n ; i++ ) { if ( tf.Y[i]!=0 ) if ( i<n-1 ) len += sprintf(H+len,"%+.3fs^%d",tf.Y[i],n-i-1); else len += sprintf(H+len,"%+.3f",tf.Y[i]); } len += sprintf(H+len,"%s",") / ("); for ( i=0 ; i<n ; i++ ) { if ( tf.U[i]!=0 ) if ( i<n-1 ) len += sprintf(H+len,"%+.3fs^%d",tf.U[i],n-i-1); else len += sprintf(H+len,"%+.3f",tf.U[i]); } len += sprintf(H+len,"%s",")"); gl_debug("%s: H(s) = %s", get_name(), (char*)H); // update A,B,C,D string (descriptive) A[0]='['; B[0]='['; C[0]='['; D[0]='['; for ( len=1,i=0 ; i<n-1 ; i++ ) { for ( j=0 ; j<n-1 ; j++ ) len += sprintf(A+len," %.3f ", ss.A[i][j]); if ( i<n-2 ) len += sprintf(A+len," %s",";"); } strcat(A," ]"); for ( len=1,i=0 ; i<n-1 ; i++ ) { len += sprintf(B+len," %.3f ", ss.B[i][0]); } strcat(B," ]"); for ( len=1,i=0 ; i<n-1 ; i++ ) { len += sprintf(C+len," %.3f ", ss.C[0][i]); } strcat(C," ]"); sprintf(D+1," %.2f ]",ss.D[0]); gl_debug("%s: A = %s", get_name(), (char*)A); gl_debug("%s: B = %s", get_name(), (char*)B); gl_debug("%s: C = %s", get_name(), (char*)C); gl_debug("%s: D = %s", get_name(), (char*)D); return 1; }