package org.singinst.uf.model; import java.awt.Color; import org.singinst.uf.math.MathUtil; public class NeuromorphicAiRelation extends YearwiseCalculationRelation { public NeuromorphicAiRelation(Node node) { super(node); } @Override protected Calculation getCalculation(final double year) { Calculation agiPossible = probabilityAiIsPossible(); Calculation sufficientHardware = new Calculation("Probability of sufficient hardware in " + (int) year) { protected double rawEvaluate(StringBuilder htmlConsole) { return probabilityOfSufficientHardware(year); } @Override public Color getColor(){ return Color.BLUE; } }; Calculation sufficientBrainImaging = probabilityOfSufficientBrainImaging(year); return new MultiplicationCalculation( "Probability of a neuromorphic AI on or before " + (int) year, agiPossible, sufficientHardware, sufficientBrainImaging ); } private Calculation probabilityOfSufficientBrainImaging(final double year) { return new CumulativeNormalDistributionCalculation( "'Probability of sufficient brain imaging in " + year + "'", ScalarValueHolder.findById(NodeIDString.Q1_5, ScalarSubIDString.MEAN), ScalarValueHolder.findById(NodeIDString.Q1_5, ScalarSubIDString.STD_DEV), Math.log10(year - ModelUtil.ANCHOR_FAR_YEAR), Color.RED); } private double probabilityOfSufficientHardware(double year) { double unboundedLogFlopsPerDollarForYear = MooreAsymptote.unboundedLnFlopsPerDollarAtYear(year); double meanLogComputingEfficiencyNeeded = meanComputingEfficiencyNeeded() * Math.log(10); double stdDevLogComputingEfficiencyNeeded = stdDevComputingEfficiencyNeeded() * Math.log(10); double muX = muX() * Math.log(10); double sigmaX = sigmaX() * Math.log(10); double numerator = 0; double denominator = 0; double z; org.singinst.uf.common.LogUtil.info(String.format("probabilityOfSufficientHardware called at year %5g, time %20.15g", (double)year, ((double) System.currentTimeMillis()) / 1000)); if (meanLogComputingEfficiencyNeeded + 10.0 * stdDevLogComputingEfficiencyNeeded > unboundedLogFlopsPerDollarForYear) { /* brute force midpoint integral, hope for Gaussian Euler-Maclaurin edge term suppression */ double logComputingEfficiency; for (int s = -100; s <= 100; s += 1) { z = (double)s/10; double slice = Math.exp(-0.5 * z * z); logComputingEfficiency = h(muX + sigmaX * z, unboundedLogFlopsPerDollarForYear); numerator += slice * MathUtil.cumulativeNormalDistribution(meanLogComputingEfficiencyNeeded, stdDevLogComputingEfficiencyNeeded, logComputingEfficiency); denominator += slice; // org.singinst.uf.common.LogUtil.info(String.format("at year %5g, z = %+8g (x = %+12.7g) d = %10g, num = %g, denom = %g", (double)year, z, sigmaX() * z, d(sigmaX() * z + muX(), year), numerator, denominator)); } org.singinst.uf.common.LogUtil.info(String.format("needed = %8g +/- %8g, bound = %8g +/- %8g, unlimited = %8g", meanLogComputingEfficiencyNeeded, stdDevLogComputingEfficiencyNeeded, muX, sigmaX, unboundedLogFlopsPerDollarForYear)); } else { double logComputingEfficiencyUpperBoundMinimum; for (int s = -100; s <= 100; s += 1) { z = (double)s/10; double slice = Math.exp(-0.5 * z * z); logComputingEfficiencyUpperBoundMinimum = hinv(meanLogComputingEfficiencyNeeded + stdDevLogComputingEfficiencyNeeded * z, unboundedLogFlopsPerDollarForYear); numerator += slice * MathUtil.cumulativeNormalDistribution(-muX, sigmaX, -logComputingEfficiencyUpperBoundMinimum); denominator += slice; } org.singinst.uf.common.LogUtil.info(String.format("bound = %8g +/- %8g, minimum = %8g +/- %8g, unlimited = %8g", muX, sigmaX, meanLogComputingEfficiencyNeeded, stdDevLogComputingEfficiencyNeeded, unboundedLogFlopsPerDollarForYear)); } org.singinst.uf.common.LogUtil.info(String.format("probabilityOfSufficientHardware called at year %5g, time %20.15g, result %20.16g", (double)year, ((double) System.currentTimeMillis()) / 1000, numerator / denominator)); return numerator / denominator; } private double meanComputingEfficiencyNeeded() { // flops divided by dollars available return getDependency().value(NodeIDString.Q1_3, ScalarSubIDString.MEAN) - getDependency().value(NodeIDString.Q1_4, ScalarSubIDString.MEAN); } private double stdDevComputingEfficiencyNeeded() { double stdDev1_3 = getDependency().value(NodeIDString.Q1_3, ScalarSubIDString.STD_DEV); double stdDev1_4 = getDependency().value(NodeIDString.Q1_4, ScalarSubIDString.STD_DEV); return Math.sqrt( stdDev1_3 * stdDev1_3 + stdDev1_4 * stdDev1_4); } /** * sum conjugated with logarithm, conjugated with negation * @param hypothetical log hardware production efficiency upper bound * @param hypothetical log hardware production efficiency if no upper bound * @return hypothetical log hardware production efficiency after effects of upper bound */ static double h(double x, double unboundedLogFlopsPerDollarForYear) { //return Math.log(exp(k) * exp(unboundedLogFlopsPerDollarForYear) / (exp(k) + exp(unboundedLogFlopsPerDollarForYear))); if (x > unboundedLogFlopsPerDollarForYear) { return unboundedLogFlopsPerDollarForYear - Math.log1p(Math.exp(unboundedLogFlopsPerDollarForYear - x)); } else { return x - Math.log1p(Math.exp(x - unboundedLogFlopsPerDollarForYear)); } } /** * * @param hypothetical log hardware production efficiency after effects of upper bound * @param hypothetical log hardware production efficiency if no upper bound * @return hypothetical log hardware production efficiency upper bound */ static double hinv(double h, double unboundedLogFlopsPerDollarForYear) { if (h >= unboundedLogFlopsPerDollarForYear) { return Double.POSITIVE_INFINITY; } else if ((h + Math.log(2)) >= unboundedLogFlopsPerDollarForYear) { return unboundedLogFlopsPerDollarForYear - Math.log(Math.expm1(unboundedLogFlopsPerDollarForYear-h)); } else { return h - Math.log1p(-Math.exp(h-unboundedLogFlopsPerDollarForYear)); } } private double muX() { return getDependency().value( NodeIDString.Q1_2, ScalarSubIDString.K50); } private double sigmaX() { return (muX() - getDependency().value( NodeIDString.Q1_2, ScalarSubIDString.K5)) / MathUtil.NINETY_FIVE_PERCENTILE; } }