/** * {@inheritDoc} * * <p>All {@code variables} must be of type {@link Discrete}. The domain of the returned variable * will be a {@link JointDiscreteDomain} with the subdomains in the same order as {@code * variables}. */ @Internal @Override public Variable createJointNoFactors(Variable... variables) { final boolean thisIsFirst = (variables[0] == this); final int dimensions = thisIsFirst ? variables.length : variables.length + 1; final DiscreteDomain[] domains = new DiscreteDomain[dimensions]; final IDatum[] subdomainPriors = new IDatum[dimensions]; domains[0] = getDomain(); subdomainPriors[0] = getPrior(); for (int i = thisIsFirst ? 1 : 0; i < dimensions; ++i) { final Discrete var = variables[i].asDiscreteVariable(); domains[i] = var.getDomain(); subdomainPriors[i] = var.getPrior(); } final JointDiscreteDomain<?> jointDomain = DiscreteDomain.joint(domains); final Discrete jointVar = new Discrete(jointDomain); jointVar.setPrior(joinPriors(jointDomain, subdomainPriors)); return jointVar; }
private MultiplexerCPD create( Discrete Y, Discrete[] Zs, int zasize, boolean oneBased, boolean aAsDouble) { Y.setLabel("Y"); java.util.Hashtable<Object, Integer> yDomainObj2index = new java.util.Hashtable<Object, Integer>(); final DiscreteDomain yDomain = Y.getDiscreteDomain(); for (int i = 0, end = yDomain.size(); i < end; i++) yDomainObj2index.put(yDomain.getElement(i), i); // Create a variable Object[] adomain = new Object[Zs.length]; for (int i = 0; i < adomain.length; i++) { int val = oneBased ? i + 1 : i; if (aAsDouble) adomain[i] = (double) val; else adomain[i] = (int) val; } Discrete A = new Discrete(adomain); A.setLabel("A"); addBoundaryVariables(Y); addBoundaryVariables(A); addBoundaryVariables(Zs); // Make all of those boundary variables Variable[] vars = new Variable[Zs.length + 2]; vars[0] = Y; vars[1] = A; for (int i = 0; i < Zs.length; i++) vars[i + 2] = Zs[i]; // Create ZA variable Object[] zaDomain = new Object[zasize]; for (int i = 0; i < zaDomain.length; i++) zaDomain[i] = i; Discrete ZA = new Discrete(zaDomain); ZA.setLabel("ZA"); // Create Z* variables Discrete[] Zstars = new Discrete[Zs.length]; for (int i = 0; i < Zstars.length; i++) { Object[] domain = new Object[Zs[i].getDiscreteDomain().size() + 1]; for (int j = 0; j < domain.length; j++) domain[j] = j; Zstars[i] = new Discrete(domain); } // Create ZA Y factor int[][] indices = new int[zasize][2]; double[] weights = new double[zasize]; int index = 0; for (int i = 0; i < Zs.length; i++) { for (int j = 0; j < Zs[i].getDiscreteDomain().size(); j++) { indices[index][0] = index; indices[index][1] = yDomainObj2index.get(Zs[i].getDiscreteDomain().getElement(j)); weights[index] = 1; index++; } } Factor f = this.addFactor(indices, weights, ZA, Y); f.setLabel("Y2ZA"); // Create ZA A factor indices = new int[zasize][2]; weights = new double[zasize]; index = 0; for (int i = 0; i < Zs.length; i++) { for (int j = 0; j < Zs[i].getDiscreteDomain().size(); j++) { indices[index][0] = index; indices[index][1] = i; weights[index] = 1; index++; } } f = this.addFactor(indices, weights, ZA, A); f.setLabel("ZA2A"); // Create ZA Z* factors // Create Z* Z factors for (int a = 0; a < Zs.length; a++) { Zs[a].setLabel("Z" + a); Zstars[a].setLabel("Z*" + a); indices = new int[zasize][2]; weights = new double[zasize]; index = 0; // Factor from ZA to Z* for (int i = 0; i < Zs.length; i++) { for (int j = 0; j < Zs[i].getDiscreteDomain().size(); j++) { indices[index][0] = index; if (a == i) { indices[index][1] = j; } else { int sz = Zs[a].getDiscreteDomain().size(); indices[index][1] = sz; } weights[index] = 1; index++; } } f = this.addFactor(indices, weights, ZA, Zstars[a]); f.setLabel("ZA2Z*"); // From Z* to Z indices = new int[Zs[a].getDiscreteDomain().size() * 2][2]; weights = new double[indices.length]; int ds = Zs[a].getDiscreteDomain().size(); for (int i = 0; i < ds; i++) { indices[i][0] = i; indices[ds + i][0] = ds; indices[i][1] = i; indices[ds + i][1] = i; weights[i] = 1; weights[ds + i] = 1; } f = this.addFactor(indices, weights, Zstars[a], Zs[a]); f.setLabel("Z*2Z"); } this._y = Y; this._a = A; this._za = ZA; this._zs = Zs; return this; }