Example #1
0
/*
 * Check if the given file is a JAR file.
 *
 * Parameters:
 *     path  - the path to the file to check for JAR magic.
 *
 * Returns:
 *     This function return NULL on success.  Otherwise, errno is set, and it
 *     returns a message that indicates what caused the failure.
 */
const char * isJar(const char * path) {
    const char * result = BAD_FILE_MSG;

    int fd = open(path, O_RDONLY);
    if (fd != -1) {
        unsigned char buf[CHUNK_SIZE];

        ssize_t count = read(fd, buf, CHUNK_SIZE);
        if (count >= MIN_SIZE) {
            result = BAD_MAGIC_MSG;

            // be sure the file is at least a ZIP file
            if (LOCSIG_AT(buf)) {

                off_t flen  = LOCNAM(buf);
                off_t xlen  = LOCEXT(buf);
                off_t start = LOCHDR + flen;
                off_t end   = start  + xlen;

                if (end <= count) {
                    while (start < end) {
                        off_t xhid  = SH(buf, start);
                        off_t xdlen = SH(buf, start + 2);

                        start += 4 + xdlen;
                        if (xhid == 0xcafe) {
                            // found the JAR magic
                            result = NULL;
                            break;
                        }
                    }
                }
            }
        }

        if (result != NULL) {
            errno = BAD_MAGIC;
        }

        close (fd);
    }

    return (result);
}
Example #2
0
void BasicHttpRequest::send_head( const char *url ) {
    const char *end = url;
    while ( *end )
        ++end;

    while ( end > url and *(--end) != '.' );

    #define SH( M, R ) \
        if ( strcmp( end, M ) == 0 ) { \
            const char s[] = "HTTP/1.0 200 OK\nContent-Type: " R "\n\n"; \
            send( s, sizeof( s ) - 1, false ); \
            return; \
        }

    SH( ".html", "text/html" );
    SH( ".css" , "text/css"  );
    SH( ".png" , "image/png" );
    SH( ".jpg" , "image/jpg" );
    SH( ".jpeg", "image/jpg" );
    SH( ".js"  , "text/javascript" );

    // default  -> plain text
    const char s[] = "HTTP/1.0 200 OK\nContent-Type: text/plain\n\n";
    send( s, sizeof( s ) - 1, false );
}
Example #3
0
/* Output the ELF header */
void output_header(unsigned char *data)
{
	Elf32_Ehdr *head;

	head = (Elf32_Ehdr*) data;

	SW(&head->e_magic, g_elfhead.iMagic);
	head->e_class = g_elfhead.iClass;
	head->e_data = g_elfhead.iData;
	head->e_idver = g_elfhead.iIdver;
	SH(&head->e_type, ELF_PRX_TYPE);
	SH(&head->e_machine, g_elfhead.iMachine);
	SW(&head->e_version, g_elfhead.iVersion);
	SW(&head->e_entry, g_elfhead.iEntry);
	SW(&head->e_phoff, g_phbase);
	SW(&head->e_shoff, g_shbase);
	SW(&head->e_flags, g_elfhead.iFlags);
	SH(&head->e_ehsize, sizeof(Elf32_Ehdr));
	SH(&head->e_phentsize, sizeof(Elf32_Phdr));
	SH(&head->e_phnum, 2);
	SH(&head->e_shentsize, sizeof(Elf32_Shdr));
	SH(&head->e_shnum, g_out_sects);
	SH(&head->e_shstrndx, g_out_sects-1);
}
Example #4
0
/*
 * Return a new initialized jzentry corresponding to a given hash cell.
 * In case of error, returns NULL.
 * We already sanity-checked all the CEN headers for ZIP format errors
 * in readCEN(), so we don't check them again here.
 * The ZIP lock should be held here.
 */
static jzentry *
newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
{
    jlong locoff;
    jint nlen, elen, clen;
    jzentry *ze;
    char *cen;

    if ((ze = (jzentry *) malloc(sizeof(jzentry))) == NULL) return NULL;
    ze->name    = NULL;
    ze->extra   = NULL;
    ze->comment = NULL;

#ifdef USE_MMAP
    if (zip->usemmap) {
        cen = (char*) zip->maddr + zc->cenpos - zip->offset;
    } else
#endif
    {
        if (accessHint == ACCESS_RANDOM)
            cen = readCENHeader(zip, zc->cenpos, AMPLE_CEN_HEADER_SIZE);
        else
            cen = sequentialAccessReadCENHeader(zip, zc->cenpos);
        if (cen == NULL) goto Catch;
    }

    nlen      = CENNAM(cen);
    elen      = CENEXT(cen);
    clen      = CENCOM(cen);
    ze->time  = CENTIM(cen);
    ze->size  = CENLEN(cen);
    ze->csize = (CENHOW(cen) == STORED) ? 0 : CENSIZ(cen);
    ze->crc   = CENCRC(cen);
    locoff    = CENOFF(cen);
    ze->pos   = -(zip->locpos + locoff);
    ze->flag  = CENFLG(cen);

    if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
    memcpy(ze->name, cen + CENHDR, nlen);
    ze->name[nlen] = '\0';
    if (elen > 0) {
        char *extra = cen + CENHDR + nlen;

        /* This entry has "extra" data */
        if ((ze->extra = malloc(elen + 2)) == NULL) goto Catch;
        ze->extra[0] = (unsigned char) elen;
        ze->extra[1] = (unsigned char) (elen >> 8);
        memcpy(ze->extra+2, extra, elen);
        if (ze->csize == ZIP64_MAGICVAL || ze->size == ZIP64_MAGICVAL ||
            locoff == ZIP64_MAGICVAL) {
            jint off = 0;
            while ((off + 4) < elen) {    // spec: HeaderID+DataSize+Data
                jint sz = SH(extra, off + 2);
                if (SH(extra, off) == ZIP64_EXTID) {
                    off += 4;
                    if (ze->size == ZIP64_MAGICVAL) {
                        // if invalid zip64 extra fields, just skip
                        if (sz < 8 || (off + 8) > elen)
                            break;
                        ze->size = LL(extra, off);
                        sz -= 8;
                        off += 8;
                    }
                    if (ze->csize == ZIP64_MAGICVAL) {
                        if (sz < 8 || (off + 8) > elen)
                            break;
                        ze->csize = LL(extra, off);
                        sz -= 8;
                        off += 8;
                    }
                    if (locoff == ZIP64_MAGICVAL) {
                        if (sz < 8 || (off + 8) > elen)
                            break;
                        ze->pos = -(zip->locpos +  LL(extra, off));
                        sz -= 8;
                        off += 8;
                    }
                    break;
                }
                off += (sz + 4);
            }
        }
    }
Example #5
0
File: psc.c Project: phines/cosmic
/*
 * Read power system data from a file and load it into a PS struct.
 */
PS GetPS(const char* file_name){
	
	//numbers of various items in the ps file.
	int i, num_buses, num_branches, num_gens, num_shunts, *ids, pv=0, sh=0, src=0;
	double base_mva;
	PS ps;
	
	//check input
	if(file_name == NULL) return NULL;
	FILE *ps_file = fopen(file_name, "r");
	if(ps_file == NULL) return NULL;
	
	//read off ps data sizes
	if(fscanf(ps_file, "BASE_MVA %lg\n", &base_mva) != 1) return NULL;
	if(fscanf(ps_file, "BUS %d\n", &num_buses) != 1) return NULL;
	if(fscanf(ps_file, "BRANCH %d\n", &num_branches) != 1) return NULL;
	if(fscanf(ps_file, "GEN %d\n", &num_gens) != 1) return NULL;
	if(fscanf(ps_file, "SHUNT %d\n", &num_shunts) != 1) return NULL;
	
	ps = malloc(sizeof(_PS));
	if(!ps) return NULL;
	ps->base_mva = base_mva;
	ps->num_buses = num_buses;
	ps->num_branches = num_branches;
	ps->num_gens = num_gens;
	ps->num_shunts = num_shunts;
	ps->num_macs = num_gens;
	
	//allocate memory for buses, branches, etc.
	ps->buses = malloc(num_buses*sizeof(Bus));	
	ps->branches = malloc(num_branches*sizeof(Branch));
	ps->gens = malloc(num_gens*sizeof(Gen));
	ps->shunts = malloc(num_shunts*sizeof(Shunt));
	ids = malloc(num_buses*sizeof(int));
	ps->src_buses = malloc((num_shunts+num_gens)*sizeof(int));
	
	//check out memory allocations
	if(!ps->buses || !ps->branches || !ps->gens || !ps->shunts || !ids || !ps->src_buses){
		FreePS(&ps);
		if(ids) free(ids);
		return NULL;
	}
	
	//read data from file and populate ps 
	fscanf(ps_file, "\n");
	for(i = 0; i < num_buses; i++){
		fscanf(ps_file, "%d %d %lg %lg %lg %lg %d %lg %lg %lg %d %lg %lg\n", BUS(id), BUS(type), BUS(pd), BUS(qd), BUS(gs), BUS(bs), BUS(area), BUS(vmag), BUS(vang), BUS(base_kv), BUS(zone), BUS(vmax), BUS(vmin));
		ids[i] = ps->buses[i].id;	
	}
	 
	//sort the bus array, get local indices, and locate the swing bus index
	qsort(ps->buses, num_buses, sizeof(Bus), CompareBuses);
	for(i = 0; i < num_buses; i++){ 
		ps->buses[i].index = i;
		ids[i] = ps->buses[i].id;
		if(ps->buses[i].type == 3) ps->swing_bus = i;	
	}
	
	//branches
	int swap_temp;
	fscanf(ps_file, "\n");
	for(i = 0; i < num_branches; i++){
		fscanf(ps_file, "%d %d %lg %lg %lg %lg %lg %lg\n", BR(from), BR(to), BR(r), BR(x), BR(b), BR(rate_a), BR(rate_b), BR(rate_c));
		
		//check whether from is greater than to, and if so, swap. this
		//helps identify parallel branches.
		if(ps->branches[i].from > ps->branches[i].to){
			swap_temp = ps->branches[i].from;
			ps->branches[i].from = ps->branches[i].to;
			ps->branches[i].to = swap_temp;
		}
		ps->branches[i].from_index = (int*)bsearch(&(ps->branches[i].from), ids, num_buses, sizeof(int), CompareBuses) - ids;
		ps->branches[i].to_index = (int*)bsearch(&(ps->branches[i].to), ids, num_buses, sizeof(int), CompareBuses) - ids;
	}
	
	//generators
	fscanf(ps_file, "\n");
	for(i = 0; i < num_gens; i++){
		fscanf(ps_file, "%d %lg %lg %lg %lg %lg %lg %d %lg %lg\n", GEN(bus), GEN(pg), GEN(qg), GEN(qmax), GEN(qmin), GEN(vsp), GEN(m_base), GEN(status), GEN(pmax), GEN(pmin));
		ps->gens[i].index = (int*)bsearch(&(ps->gens[i].bus), ids, num_buses, sizeof(int), CompareBuses) - ids;
		ps->gens[i].pg/=base_mva;
		ps->gens[i].qg/=base_mva;
	}
	qsort(ps->gens, ps->num_gens, sizeof(Gen), CompareGen);
	
	//shunts
	fscanf(ps_file, "\n");
	for(i = 0; i < num_shunts; i++){
		fscanf(ps_file, "%d %lg %lg\n", SH(bus), SH(p), SH(q));
		ps->shunts[i].index = (int*)bsearch(&(ps->shunts[i].bus), ids, num_buses, sizeof(int), CompareBuses) - ids;
		ps->shunts[i].p/=base_mva;
		ps->shunts[i].q/=base_mva;
	}
	qsort(ps->shunts, ps->num_shunts, sizeof(Shunt), CompareShunt);
	
	//find the set union of load and generator buses
	while(sh < num_shunts || pv < num_gens){
		if(pv==num_gens){ps->src_buses[src++] = ps->shunts[sh++].index; continue;}
		if(sh==num_shunts){ps->src_buses[src++] = ps->gens[pv++].index; continue;}
		if(ps->shunts[sh].index==ps->gens[pv].index){ 
			ps->src_buses[src++] = ps->shunts[sh++].index;
			pv++;
			continue;
		}
		ps->src_buses[src++] = (ps->shunts[sh].index < ps->gens[pv].index ? ps->shunts[sh++].index : ps->gens[pv++].index);
	}
	
	//free up any extra memory in the source bus array
	realloc(ps->src_buses, src*sizeof(int));
	ps->num_src = src;
	
	//create ybus. if there are any errors, free allocated memory and
	//return NULL
	if(CreateYBus(ps, ids)){
		FreePS(&ps);
		free(ids);
		return NULL;
	}
	
	//release the bus map
	free(ids); 
	 
	//return success
	return ps;
};
Example #6
0
ulg LG(uch* p) { return ((ulg)(SH(p)) | ((ulg)(SH((p)+2)) << 16)); }
Example #7
0
/* bjartek atreus layout for norwegian keyboard
 * - all the mods are oneshot. see here for information about this. https://github.com/tmk/tmk_keyboard/blob/master/tmk_core/doc/keymap.md
 * - layer one has norwegian special characters at AEO positions
 * - needs us mac keyboard layout
 */

const uint16_t PROGMEM actionmaps[][MATRIX_ROWS][MATRIX_COLS] = {
KEYMAP(
Q       , W        , E        , R        , T          ,                       Y         , U         , I       , O         , P        , \
A       , S        , D        , F        , G          ,                       H         , J         , K       , L         , SCLN     , \
Z       , X        , C        , V        , B          ,                       N         , M         , COMM    , DOT       , SLSH     , \
ESC     , OSM(RALT), OSM(LCTL), OSM(LSFT), TAP(1,BSPC), OSM(LGUI), OSM(LALT), TAP(2,SPC), TAP(3,TAB), MINS    , QUOT      , ENT     ),

KEYMAP(
AGK(F7) , GUI(F12) , RA(QUOT) , ACK(R)   , AGSK(L)    ,                       SH(6)     , SH(LBRC)  , SH(RBRC), RA(O)     , SH(1)    , \
RA(A)   , GUI(LBRC), CSK(ENT) , GUI(RBRC), GSK(T)     ,                       0         , SH(9)     , SH(0)   , SH(BSLS)  , SH(4)    , \
GSK(A)  , GSK(F)   , CTRL(T)  , ALT(V)   , GUI(F9)    ,                       GRAVE     , LBRC      , RBRC    , SH(7)     , SH(GRAVE), \
GA      , OSM(RALT), OSM(LCTL), OSM(LSFT), TRNS       , OSM(LGUI), OSM(LALT), CTRL(F2)  , OFF(1)    , SH(2)   , QUOT      , OSM(LGUI)),

KEYMAP(
INS     , HOME     , UP       , END      , PGUP       ,                       SH(5)     , 7         , 8       , 9         , SH(8)    , \
DEL     , LEFT     , DOWN     , RIGHT    , PGDN       ,                       MINS      , 4         , 5       , 6         , SH(EQUAL), \
VOLU    , MPRV     , MPLY     , MNXT     , GCK(Q)     ,                       SH(4)     , 1         , 2       , 3         , BSLS     , \
VOLD    , MUTE     , OSM(LCTL), OSM(LSFT), CSK(SPC)   , OSM(LGUI), OSM(LALT), TRNS      , OFF(1)    , DOT     , 0         , KP_EQUAL),

KEYMAP(
F1      , F2       , F3       , F4       , F5         ,                       WH_D      , BTN1      , MS_U    , BTN2      , SH(3)    , \
F6      , F7       , F8       , F9       , F10        ,                       WH_U      , MS_L      , MS_D    , MS_R      , BTN3     , \
F11     , F12      , F13      , F14      , BOOT       ,                       NO        , ACL0      , NO      , NO        , NO       , \
GA      , OSM(RALT), OSM(LCTL), OSM(LSFT), GS         , OSM(LGUI), OSM(LALT), SPC       , TRNS      , MINS    , SH(BSLS)  , KP_EQUAL)
#define AC_NO_AE KC_QUOT
#define AC_NO_OE KC_SCLN
#define AC_NO_LT KC_NONUS_BSLASH
#define AC_NO_PLUS KC_MINS
#define AC_NO_BSLS KC_EQUAL
#define AC_NO_QUOTE KC_BSLS
#define AC_NO_MINS KC_SLSH
#define AC_NO_PIPE KC_GRAVE


const uint16_t PROGMEM actionmaps[][MATRIX_ROWS][MATRIX_COLS] = {
  KEYMAP( /* 0: mostly letters */
    Q,   W,         E,         R,         T,   					   /*|,, |*/         Y,              U,         I,   	          O,    P,    \
    A,   S,         D,         F,         G,   					   /*|,, |*/         H,              J,         K,   	          L,    COMM, \
		Z,   X,         C,         V,         B,               /*|,, |*/         N,              M,         COMM,           DOT,  KP_SLASH, \
    ESC, TAPT(3),   OSM(LGUI), OSM(LSFT), MK(LCTL,BSPC), TAPT(1), TAPT(2),   MK(LALT,SPC),   TACK(TAB), TACSK(SLSH), SH(2), ENT
  ),
  KEYMAP( /* layer one is mostly for programming and shell. lots of idea shortcute on left, not sure how much i will use them.*/
    ACK(7),  CTRL(W),    NO_AE,      SH(F10),     ACSK(L),                     SH(NO_ACNT), RA(7), RA(0), NO_OE,   SH(1), \
    NO_AA,   ACK(LEFT),  CSK(ENT),   ACK(RIGHT),  ALT(INS),                    0,           SH(8), SH(9), NO_PIPE, RA(4), \
    CSK(A),  CSK(F),     ACSK(T),    ALT(V),      CTRL(F9),                    SH(NO_BSLS), RA(8), RA(9), SH(6),   RA(NO_ACNT), \
    ESC,     TRNS,       OSM(LGUI),  OSM(LSFT),   TRNS,    TRNS,    TRNS,      SPC,         OFF(1),RA(2), NO_QUOTE,KP_EQUAL
  ),
  KEYMAP( /* hold space brings up move pad and numpad */
    INS,      HOME,   UP  ,      END  ,     PGUP,                          SH(5),         7     , 8  , 9, SH(NO_QUOTE),     \
    DEL,      LEFT,   DOWN,      RIGHT,     PGDN,                          NO_MINS,       4     , 5  , 6, NO_PLUS, \
    GUI(1),   GUI(2), GUI(3),    GUI(4),    GUI(5),                        RA(4),         1     , 2  , 3, NO_BSLS,      \
    ACK(DEL), TRNS, OSM(LGUI), OSM(LSFT),   GUI(D) , TRNS, TRNS,           MK(LALT,SPC),  OFF(1), DOT, 0, KP_EQUAL
  ),
  KEYMAP( /* hold tab to have fpad and mouse */
    F1,     F2,    F3,        F4,         F5,                             WH_D ,           BTN1   ,  MS_U ,         BTN2 ,      SH(3) , \
Example #9
0
int fixup_imports(void)
{
	unsigned int *pText;
	unsigned int *pNid;
	struct PspModuleImport *pLastImport = NULL;
	int count;

	/* First let's check the sizes are correct */
	if(g_stubtext->iSize != (g_nid->iSize * 2))
	{
		fprintf(stderr, "Error, size of text section and nid section do not match\n");
		return 0;
	}

	count = g_nid->iSize / 4;
	pText = (unsigned int *) g_stubtext->pData;
	pNid = (unsigned int *) g_nid->pData;

	if(g_verbose)
	{
		fprintf(stderr, "Import count %d\n", count);
	}

	while(count > 0)
	{
		unsigned int stub_addr;
		unsigned int stub_nid;
		unsigned int sect_nid;

		stub_addr = LW(pText[0]);
		stub_nid  = LW(pText[1]);
		sect_nid  = LW(pNid[0]);

		/* Check if this is an original format NID */
		if((stub_addr != MIPS_JR_31) || (stub_nid != MIPS_NOP))
		{
			struct PspModuleImport *pImport;
			u16    func_count;

			if(g_verbose)
			{
				fprintf(stderr, "Found import to fixup. pStub %08X, Nid %08X, NidInSect %08X\n", stub_addr, stub_nid, sect_nid);
			}

			if(stub_nid != sect_nid)
			{
				fprintf(stderr, "Error, unmatched NIDs\n");
				return 0;
			}

			if((stub_addr < g_libstub->iAddr) || (stub_addr > (g_libstub->iAddr + g_libstub->iSize)) || (stub_addr & 3))
			{
				fprintf(stderr, "Error, invalid stub address\n");
				return 0;
			}

			pImport = (struct PspModuleImport *) (g_libstub->pData + (stub_addr - g_libstub->iAddr));
			if(g_verbose)
			{
				fprintf(stderr, "Import Stub %p, %08X, %08X, %02X, %02X, %04X, %08X, %08X\n", pImport, 
						LW(pImport->name), LW(pImport->flags), pImport->entry_size, pImport->var_count, 
						LH(pImport->func_count), LW(pImport->nids), LW(pImport->funcs));
			}

			func_count = LH(pImport->func_count);

			if(func_count == 0)
			{
				/* Setup the stub */
				SW(&pImport->nids, ((unsigned char *) pNid - g_nid->pData) + g_nid->iAddr);
				SW(&pImport->funcs, ((unsigned char *) pText - g_stubtext->pData) + g_stubtext->iAddr);
			}
			else
			{
				if((pLastImport) && (pImport != pLastImport))
				{
					fprintf(stderr, "Error, could not fixup imports, stubs out of order.\n");
					fprintf(stderr, "Ensure the SDK libraries are linked in last to correct this error\n");
					return 0;
				}
			}

			pLastImport = pImport;
			func_count++;
			SH(&pImport->func_count, func_count);
			SW(&pText[0], MIPS_JR_31);
			SW(&pText[1], MIPS_NOP);
		}
		else
		{
			/* Set last import to some value so we know if we have out of order stubs over a fixed stub table */
			pLastImport = (struct PspModuleImport *) pText;
		}

		pText += 2;
		pNid++;
		count--;
	}

	/* Should indicate no error occurred */
	if(count == 0)
	{
		if(g_verbose)
		{
			fprintf(stderr, "No libraries to fixup\n");
		}
	}

	return 1;
}
Example #10
0
void Bayes::sample_muOmega() {
  double tau = 10.0;
  int d0 = p + 2;
  // matrix_t S0(p, p);
  ublas::matrix<double> S0(p, p);
  S0 = d0 * ublas::identity_matrix<double>(p, p)/4.0;
  
  std::vector<int> idx;
  ublas::indirect_array<> irow(p);
  // projection - want every row
  for (size_t i=0; i<irow.size(); ++i)
    irow(i) = i;
  
  // size_t rank;
  ublas::matrix<double> S(p, p);
  // matrix_t SS(p, p);
  ublas::matrix<double> SS(p, p);
  ublas::matrix<double> Omega_inv(p, p);

  // identity matrix for inverting cholesky factorization
  ublas::matrix<double> I(p, p);
  I.assign(ublas::identity_matrix<double> (p, p));
  ublas::symmetric_adaptor<ublas::matrix<double>, ublas::upper> SH(I);

  // triangular matrix for cholesky_decompose
  ublas::triangular_matrix<double, ublas::lower, ublas::row_major> L(p, p);

  int df;
  for (int j=0; j<k; ++j) {
    idx = find_all(z, j);
    int n_idx = idx.size();

    ublas::matrix<double> xx(p, n_idx);
    ublas::matrix<double> e(p, n_idx);
    // ublas::matrix<double> m(p, 1);
    ublas::vector<double> m(p);

    ublas::indirect_array<> icol(n_idx);
    for (size_t i=0; i<idx.size(); ++i)
      icol(i) = idx[i];
    if (n_idx > 0) {
      double a = tau/(1.0 + n_idx*tau);
      //! REFACTOR - should be able to do matrix_sum directly on projection rather than make a copy?
      xx.assign(project(x, irow, icol));
      m.assign(ublas::matrix_sum(xx, 1)/n_idx);
      // e.assign(xx - outer_prod(column(m, 0), ublas::scalar_vector<double>(n_idx, 1)));
      e.assign(xx - outer_prod(m, ublas::scalar_vector<double>(n_idx, 1)));
      S.assign(prod(e, trans(e)) + outer_prod(m, m) * n_idx * a/tau);
      // SS = trans(S) + S0;
      SS = S + S0;
      df = d0 + n_idx;

      // Omega(j).assign(wishart_rnd(df, SS));
      Omega(j).assign(wishart_InvA_rnd(df, SS));
      SH.assign(Omega(j));
      cholesky_decompose(SH, L);
      Omega_inv.assign(solve(SH, I, ublas::upper_tag()));
      mu(j).assign(a*n_idx*m + sqrt(a)*prod(Omega_inv, Rmath::rnorm(0, 1, p)));
    } else {
      // Omega(j).assign(wishart_rnd(d0, S0));
      Omega(j).assign(wishart_InvA_rnd(d0, S0));
      SH.assign(Omega(j));
      cholesky_decompose(SH, L);
      Omega_inv.assign(solve(SH, I, ublas::upper_tag()));
      mu(j).assign(sqrt(tau) * prod(Omega_inv, Rmath::rnorm(0, 1, p)));
    }
  }
}