首页 > 解决方案 > ArithmeticException:函数不接受浮点非数字值。PointwiseSign() 在 Unity WebGL 中不起作用

问题描述

我在 Unity 中有一个功能,目前在 Unity 编辑器和 Windows 构建中有效,但在 WebGL 构建中无效。在浏览器中,我收到以下错误:

  at System.Math.Sign (System.Double value) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Double.Vector+<>c.<DoPointwiseSign>b__31_0 (System.Double x) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Func`2[T,TResult].Invoke (T arg) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Storage.DenseVectorStorage`1+<>c__DisplayClass30_0`1[T,TU].<MapToUnchecked>b__0 (System.Int32 a, System.Int32 b) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Action`2[T1,T2].Invoke (T1 arg1, T2 arg2) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.Threading.CommonParallel.For (System.Int32 fromInclusive, System.Int32 toExclusive, System.Int32 rangeSize, System.Action`2[T1,T2] body) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Storage.DenseVectorStorage`1[T].MapToUnchecked[TU] (MathNet.Numerics.LinearAlgebra.Storage.VectorStorage`1[T] target, System.Func`2[T,TResult] f, MathNet.Numerics.LinearAlgebra.Zeros zeros, MathNet.Numerics.LinearAlgebra.ExistingData existingData) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Storage.VectorStorage`1[T].MapTo[TU] (MathNet.Numerics.LinearAlgebra.Storage.VectorStorage`1[T] target, System.Func`2[T,TResult] f, MathNet.Numerics.LinearAlgebra.Zeros zeros, MathNet.Numerics.LinearAlgebra.ExistingData existingData) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Vector`1[T].Map (System.Func`2[T,TResult] f, MathNet.Numerics.LinearAlgebra.Vector`1[T] result, MathNet.Numerics.LinearAlgebra.Zeros zeros) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Double.Vector.DoPointwiseSign (MathNet.Numerics.LinearAlgebra.Vector`1[T] result) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Action`1[T].Invoke (T obj) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Vector`1[T].PointwiseUnary (System.Action`1[T] f) [0x00000] in <00000000000000000000000000000000>:0 
  at MathNet.Numerics.LinearAlgebra.Vector`1[T].PointwiseSign () [0x00000] in <00000000000000000000000000000000>:0 
  at EBM.Integrate (MathNet.Numerics.LinearAlgebra.Vector`1[T] T, System.Int32 years, System.Int32 timesteps) [0x00000] in <00000000000000000000000000000000>:0 
  at EBM.Calc (System.Collections.Generic.IEnumerable`1[T] input, System.Int32 years, System.Int32 timesteps) [0x00000] in <00000000000000000000000000000000>:0 
  at World.Calc (System.Boolean useTemp, System.Int32 years, System.Int32 steps) [0x00000] in <00000000000000000000000000000000>:0 
  at World.Init () [0x00000] in <00000000000000000000000000000000>:0 
  at GameManager.Awake () [0x00000] in <00000000000000000000000000000000>:0 
 
(Filename: currently not available on il2cpp Line: -1)

导致错误的函数是这里的 Integrate() 函数:

/// <summary> Does entire timestep integration calculation </summary>
    public static (Matrix<double>, Matrix<double>) Integrate(Vector<double> T = null, int years = 0, int timesteps = 0)
    {
        T = T ?? 7.5f + 20 * (1 - 2 * x.PointwisePower(2));
        years = years == 0 ? dur : years;
        timesteps = timesteps == 0 ? nt : timesteps;
        Matrix<double> Tfin = Matrix<double>.Build.Dense(bands, nt, 0);
        Matrix<double> Efin = Matrix<double>.Build.Dense(bands, nt, 0);
        Matrix<double> T0fin = Matrix<double>.Build.Dense(bands, nt, 0);
        Matrix<double> ASRfin = Matrix<double>.Build.Dense(bands, nt, 0);
        
        //Matrix<double> tfin = Matrix<double>.Build.Dense()np.linspace(0, 1, nt);
        Vector<double> Tg = Vector<double>.Build.DenseOfVector(T);
        Vector<double> E = Tg * cw;
        
        for (var (i, p) = (0, 0); i < years; i++)
        {
            for (int j = 0; j < timesteps; j++)
            {
                /*              if (j % (nt / 100f) == 0)
                                {
                                    Efin.SetColumn(p, E);
                                    Tfin.SetColumn(p, T);
                                    p++;
                                }*/
                Vector<double> alpha = E.PointwiseSign().PointwiseMultiply(aw).Map(x => x < 0 ? aI : x); // aw * (E > 0) + ai * (E < 0)
                Vector<double> C = alpha.PointwiseMultiply(S.Row(j)) + cg_tau * Tg - A + F; // alpha * S[i, :] + cg_tau * Tg - A
                Vector<double> T0 = C / (M - k * Lf / E);

                if (i == dur - 1)
                {
                    Efin.SetColumn(j, E);// [":", i] = E;
                    Tfin.SetColumn(j, T);//[":", i] = T;
                    T0fin.SetColumn(j, T0);//[":", i] = T0;
                    ASRfin.SetColumn(j, alpha.PointwiseMultiply(S.Row(j)));//[":", i] = alpha * S[i, ":"];
                }

                T = Sign0(GreatOrE, E) / cw + Sign0(Less, Sign0(Less, E, T0)); // E/cw*(E >= 0)+T0*(E < 0)*(T0 < 0)
                E = E + dt * (C - M * T + Fb);
                var mklfe = M - k * Lf / E;
                var signlesset0 = Sign0(Less, E, T0);

                /*# Implicit Euler on Tg
                # latent heat transport
                # n.b. this is semi-implicit, with some derivatives are
                # calculated on the previous time step*/
                var q = RH * saturation_specific_humidity(Tg, Ps);
                var rhs1 = (dt * diffop / cg) * (Lv * q / cp);
                Tg = (kappa - Matrix<double>.Build.DiagonalOfDiagonalVector(
                    Sign0(Less, signlesset0, dc / mklfe) // np.diag(dc / (M - kLf / E) * (T0 < 0) * (E < 0)
                )).Solve(Tg + rhs1 + dt_tau * (
                    Sign0(GreatOrE, E) / cw + (aI * S.Row(j) - A + F). // E / cw * (E >= 0) + (ai * S[i, :] - A)
                    Map2((a, b) => b != 0 ? a / b : 0, // funky division
                        Sign0(Less, signlesset0, mklfe)) // (M - kLf / E) * (T0 < 0) * (E < 0)
                ));
            }
        }

根据堆栈跟踪,看起来问题出在该行上Vector<double> alpha = E.PointwiseSign().PointwiseMultiply(aw).Map(x => x < 0 ? aI : x);

我不明白为什么代码在其他版本的游戏中有效,但在 WebGL 版本中中断。任何帮助,将不胜感激。

标签: unity3dunity-webgl

解决方案


想出了一种解决方案——出于某种原因,这在 Unity 2019.3 中随机中断,但升级到 2019.4,现在该功能似乎一直在工作。可能与不同版本如何将函数转换为 WebGL 有关。


推荐阅读