Невозможно доказать буквально ошибку при попытке создать символическую функцию на основе существующей функции

Мне нужно найти обратную функцию виртуального значения логнормальных случайных величин. Вот что я пытался сделать:

syms flogn(x,p1,p2)
% assume(p2<=0);             %Adding this doesn't change the error
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);
glogn = finverse(flogn,x);

Но я получил ошибку:

Error using symengine
Unable to prove 'p2 <= 0' literally. Use 'isAlways' to test the statement mathematically.

Error in sym/subsindex (line 810)
                X = find(mupadmex('symobj::logical',A.s,9)) - 1;

Error in sym/privsubsasgn (line 1085)
                L_tilde2 = builtin('subsasgn',L_tilde,struct('type','()','subs',{varargin}),R_tilde);

Error in sym/subsasgn (line 922)
            C = privsubsasgn(L,R,inds{:});

Error in logncdf>locallogncdf (line 73)
sigma(sigma <= 0) = NaN;

Error in logncdf (line 47)
[varargout{1:max(1,nargout)}] = locallogncdf(uflag,x,varargin{:});

Error in Untitled5 (line 3)
flogn(x,p1,p2) = x - logncdf(x,p1,p2,'upper')/lognpdf(x,p1,p2);

Я также пробовал с бета-версией и получил аналогичную ошибку. Как я могу использовать logncdf с символическими переменными?


person cauthon14    schedule 12.11.2018    source источник
comment
Эта проблема аналогична символьному индексированию.   -  person alpereira7    schedule 21.11.2018
comment
Эта проблема очень похожа на эту.   -  person alpereira7    schedule 21.11.2018


Ответы (1)


Обратите внимание, что вы могли бы еще больше минимизировать код примера, например:

syms flogn(x,p1,p2)
flogn(x,p1,p2) = logncdf(x,p1,p2);

Он короче, выдает ту же ошибку и помогает нам сосредоточиться на источнике сообщения об ошибке.


Таким образом, ошибка возникает не из-за попытки инвертировать функцию, а из-за попытки использовать существующую функцию для числовых вычислений с символическими переменными.

Ошибка возникает из-за того, что вы хотите создать символьную функцию flogn на основе существующей функции logncdf, а logncdf имеет несколько сравнений.

С помощью команды edit logncdf вы можете прочитать исходный код функции и увидеть сравнение в строках 73 и 76.

% Return NaN for out of range parameters.
sigma(sigma <= 0) = NaN;

% Negative data would create complex values, which erfc cannot handle.
x(x < 0) = 0;

Matlab не может сравнивать символы, поэтому выдает ошибки.

В зависимости от того, что вам действительно нужно, у вас могут быть разные решения.

  • Вам действительно нужно символизировать функцию flogn? Не могли бы вы просто написать это как function, а затем вычислить обратное значение (если оно может быть инвертировано...)?

  • Если вы действительно хотите сохранить символы, вы также можете переписать свою собственную функцию logncdf (с другим именем), чтобы в ней не было сравнений. Но все еще не гарантируется, что вы найдете обратное.

person alpereira7    schedule 20.11.2018
comment
Спасибо за предложение по минимизации. Буду иметь в виду в следующий раз. - person cauthon14; 22.11.2018
comment
Мне не нужно символизировать функцию. Но как мне вычислить обратное без него? На данный момент я обошел проблему, но все же хотел бы узнать ваше мнение по этому поводу. Является ли единственным способом создание массива чисел X, а затем вычисление y = fzero(f(x)-x) для всех x в X? - person cauthon14; 22.11.2018
comment
@cauthon14 Привет! Я бы рекомендовал использовать fzero, как вы сказали. Я предлагаю прочитать это или много вопросы по подобным темам задавались здесь, в SO. Если вы все еще не нашли решения в существующих вопросах в SO, не стесняйтесь задавать новый вопрос. С уважением. - person alpereira7; 22.11.2018