2012-03-08 3 views
0

Я написал класс Matlab для обработки dual numbers, чтобы сделать automatic differentiation. Для почти всех случаев это отлично работает, и новый класс является заменой для других числовых классов в большинстве функций (поле «x» дает значения функции, а поле d дает значение производной от функция в этой точке.)Содействие левой стороне оператора присваивания

>> x = mkdual([1 2 3]); 
>> x.^2 
ans = 
    Dual 

    Properties: 
    x: [1 4 9] 
    d: [2 4 6] 

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

>> y=zeros(2) // Pre-allocate for speed 
y = 
    0  0 
    0  0 
>> x = 1; 
>> y(1,:)=x 
y = 
    1  1 
    0  0 

К сожалению, это не поможет с моим классом, так как он не может способствовать массив на LHS оператора присваивания к двойственного числа:

>> x=mkdual(1); 
>> y(2,:)=x 
??? The following error occurred converting from Dual to double: 
Error using ==> double 
Conversion to double from Dual is not possible. 

Может ли кто-нибудь предложить исправление или обходное решение - предпочтительно такое, которое позволяет автоматически продвигать переменную y в Dual?

ответ

2

Ваш пример не подведет, потому что он не может способствовать y к Dual; он терпит неудачу, потому что пытается преобразовать x в двойное, и не может.

Если вы хотите сделать это, вы можете добавить перегруженный метод double в Dual, который выполнит операцию преобразования.

Я предполагаю, что это не то, что вы хотите, но, скорее, вам нужен способ предварительного распределения массива фиктивных элементов класса Dual. Для этого вы можете сконструировать конструктор Dual так, чтобы он работал без входных аргументов, возвращая фиктивный или по умолчанию Dual. Тогда вы можете сказать y(2,2) = Dual, и у вас будет 2x2 предварительно выделенный массив манекена Dual s.

Поиск в документе для 'Инициализация массивов объектов значений' для более полного примера.

В качестве альтернативы вы можете сделать y массив ячеек вместо массива.

+0

Это аккуратная идея, спасибо. –

1

Вы не сможете автоматически рекламировать y до Dual, если только вы не замените переменную целиком (что не дает преимущества предварительного использования).

Однако вы должны иметь возможность предварительно распределить его как Dual в первую очередь. Я не уверен, синтаксиса, и это может зависеть от реализации, но что-то вроде:

mkdual(zeros(10,10)) 

В качестве альтернативы, вы можете сделать ленивую предварительно выделение с помощью петли в обратном направлении. То есть, вместо того, чтобы

for ix = 1:100 
    y(ix) = mkdual(...) 
end 

Использование

for ix = 100:-1:1 
    y(ix) = mkdual(...) 
end 
+0

Спасибо за ответ. Я подозреваю, что могу переписать некоторые из моих функций на «двойные версии», которые выполняют соответствующие предварительные выделения как двойные числа. Я надеялся, что было бы решение, которое позволило бы мне сбрасывать двойной массив в качестве аргумента без каких-либо изменений в функции, но, похоже, этого не происходит.Приемлемым решением «второго наилучшего» было бы восстановление функций, чтобы они работали как с обычным, так и с двойным числом, но я не уверен, насколько это возможно. –

Смежные вопросы