{"record":{"id":"82069c38c8ca3947","repo":"stanfordnlp/CoreNLP","slug":"parameters-must-be-non-negative","errorCode":null,"errorMessage":"Parameters must be non-negative!","messagePattern":"Parameters must be non-negative!","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/stats/Dirichlet.java","lineNumber":25,"sourceCode":" *\n * @author Jenny Finkel\n */\n\npublic class Dirichlet<E> implements ConjugatePrior<Multinomial<E>, E> {\n\n  private static final long serialVersionUID = 1L;\n\n  private Counter<E> parameters;\n\n  public Dirichlet(Counter<E> parameters) {\n    checkParameters(parameters);\n    this.parameters = new ClassicCounter<>(parameters);\n  }\n\n  private void checkParameters(Counter<E> parameters) {\n    for (E o : parameters.keySet()) {\n      if (parameters.getCount(o) < 0.0) {\n        throw new RuntimeException(\"Parameters must be non-negative!\");\n      }\n    }\n    if (parameters.totalCount() <= 0.0) {\n      throw new RuntimeException(\"Parameters must have positive mass!\");\n    }\n  }\n\n  public Multinomial<E> drawSample(Random random) {\n    return drawSample(random, parameters);\n  }\n  \n  public static <F> Multinomial<F> drawSample(Random random, Counter<F> parameters) {\n    Counter<F> multParameters = new ClassicCounter<>();\n    double sum = 0.0;\n    for (F o : parameters.keySet()) {\n      double parameter = Gamma.drawSample(random, parameters.getCount(o));\n      sum += parameter;\n      multParameters.setCount(o, parameter);","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/stats/Dirichlet.java#L7-L43","documentation":"A Dirichlet distribution's parameters are concentration values and must be non-negative; negative counts are mathematically invalid. The constructor copies the given Counter and validates it via checkParameters, throwing RuntimeException if any parameter count is negative.","triggerScenarios":"Calling a Dirichlet constructor with a Counter containing at least one negative count, e.g. built from differences or decremented counts that went below zero.","commonSituations":"Parameter counters derived from arithmetic (posterior updates, subtraction of expected counts) that produced negative values due to numerical issues or logic bugs.","solutions":["Validate/clip counts before constructing: Math.max(0, count) for each parameter.","Fix the upstream computation producing negative counts (e.g. subtracting more than present).","If negative values are legitimate pseudo-data offsets, shift all counts by a constant to make them non-negative."],"exampleFix":"// before\nCounter<String> params = diffOfCounters(prior, posterior); // may go negative\nDirichlet<String> d = new Dirichlet<>(params); // throws\n// after\nfor (String k : params.keySet()) params.setCount(k, Math.max(0.0, params.getCount(k)));\nDirichlet<String> d = new Dirichlet<>(params);","handlingStrategy":"validation","validationCode":"boolean valid = parameters.keySet().stream().allMatch(k -> parameters.getCount(k) >= 0.0);\nif (!valid) throw new IllegalArgumentException(\"Dirichlet parameters must be non-negative\");","typeGuard":null,"tryCatchPattern":"try {\n  Dirichlet<E> d = new Dirichlet<>(parameters);\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"non-negative\")) {\n    parameters.keySet().forEach(k -> parameters.setCount(k, Math.max(0.0, parameters.getCount(k))));\n    // retry once with clipped parameters\n  } else throw e;\n}","preventionTips":["Clip counts to >= 0 after any arithmetic on parameter counters.","Audit subtraction-based posterior updates for underflow below zero.","Validate inputs at the boundary where parameter counters are built."],"tags":["validation","negative-value","statistics"],"backgroundTag":"invalid-argument-value","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}