Вот код, который все еще векторизован, и он не использует многопоточность. На моем компьютере он более чем в два раза быстрее оригинала, но кое-что еще можно сделать здесь.
Кстати, я серьезно сомневаюсь, что код Matlab особенно оптимизирован, так как происходят некоторые очень расточительные операции - ненужное распределение, ненужные операции (sum(w.*1)
действительно плохо, умножение массива на 1 и выделение дополнительного массива в процессе это ужасно расточительно :) Кроме того, вам не нужно выделять какие-либо векторы xx_0_0
, xx_1_0
в Matlab, вы можете просто использовать трансляцию, как в Джулии.
Во всяком случае, вот моя первая попытка:
function fit_xlin2(x, y, w)
regularization = 1.0e-5
sumwx = (w' * x) + regularization
sumwy = (w' * y)
sumwxx = sum(a[1]*a[2]^2 for a in zip(w, x))
sumwxy = sum(prod, zip(w, x, y))
wx = w .* x
xxk_0_0 = sum(w) .- w
xxk_1_0 = sumwx .- wx
xxk_1_1 = sumwxx .- wx .* x
xyk_0 = sumwy .- w .* y
xyk_1 = sumwxy .- wx .* y
det = xxk_0_0 .* xxk_1_1 .- xxk_1_0 .* xxk_1_0
c0 = (xxk_1_1 .* xyk_0 .- xxk_1_0 .* xyk_1)./det
c1 = (-xxk_1_0 .* xyk_0 .+ xxk_0_0 .* xyk_1)./det
return c0 .+ c1 .* x
end
Редактировать: Вы можете получить достаточное ускорение, если де-векторизовать основной цикл. Этот код примерно в 17 раз быстрее исходного кода Julia, все еще однопоточный и достаточно читаемый:
function fit_xlin_loop(x, y, w)
if !(size(x) == size(y) == size(w))
error("Input vectors must have the same size.")
end
regularization = 1.0e-5
sumw = sum(w)
sumwx = (w' * x) + regularization
sumwy = (w' * y)
sumwxx = sum(a[1]*a[2]^2 for a in zip(w, x))
sumwxy = sum(prod, zip(w, x, y))
y_est = similar(x)
@inbounds for i in eachindex(y_est)
wx = w[i] * x[i]
xxk_0_0 = sumw - w[i]
xxk_1_0 = sumwx - wx
xxk_1_1 = sumwxx - wx * x[i]
xyk_0 = sumwy - w[i] * y[i]
xyk_1 = sumwxy - wx * y[i]
det = xxk_0_0 * xxk_1_1 - xxk_1_0 * xxk_1_0
c0 = (xxk_1_1 * xyk_0 - xxk_1_0 * xyk_1) / det
c1 = (-xxk_1_0 * xyk_0 + xxk_0_0 * xyk_1) / det
y_est[i] = c0 + c1 * x[i]
end
return y_est
end
Хм, после некоторого рытья кажется что при предоставлении os.listdir строки unicode, этого вида работ:
files = os.listdir(u'test_source')
for f in files:
pf = os.path.join(u'test_source', f)
print pf.encode('ascii', 'replace'), os.path.exists(pf)
===>
test_source\ex True
test_source\joe True
test_source\mie.txt True
test_source\__()'''.txt True
test_source\????.txt True
Некоторые важные наблюдения здесь:
os.listdir
(и подобные функции, как os.walk
) должен быть передан строка unicode для работы правильно с путями unicode. Вот кавычка из вышеупомянутой ссылки:os.listdir (), который возвращает имена файлов, поднимает вопрос: это должно возвратить версию Unicode имен файлов, или это должно возвратить 8-разрядные строки, содержащие закодированные версии? os.listdir () сделает обоих, в зависимости от того, обеспечили ли Вы путь к каталогу как 8-разрядную строку или строку Unicode. При передаче строки Unicode как пути имена файлов будут декодироваться с помощью кодирования файловой системы, и список строк Unicode будет возвращен, в то время как передача 8-разрядного пути возвратит 8-разрядные версии имен файлов.
print
хочет строку ASCII, не unicode, таким образом, путь должен быть закодирован к ASCII.Это работает как очарование с помощью Python 2.5.1 на OS X:
subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True
Возможно, это означает, что это имеет отношение к Windows XP так или иначе?
Править: Я также пытался строками unicode судить имитатора поведение Windows лучше:
for f in os.listdir(u'subdir'):
pf = os.path.join(u'subdir', f)
print pf, os.path.exists(pf)
subdir/bar.txt True
subdir/foo.txt True
subdir/עִבְרִית.txt True
В Терминале (OS x приложение командной строки запаса), который является. Используя НЕАКТИВНЫЙ это все еще работало, но не распечатало имя файла правильно. Для проверки это действительно - unicode там, я проверил:
>>>os.listdir(u'listdir')[2]
u'\u05e2\u05b4\u05d1\u05b0\u05e8\u05b4\u05d9\u05ea.txt'
Это похоже на Unicode по сравнению с проблемой ASCII - os.listdir
возвращает список строк ASCII.
Править: Я попробовал его на Python 3.0, также на XP SP2, и os.listdir
просто опущенный еврейские имена файлов вместо того, чтобы перечислить их вообще.
Согласно документам, это означает, что не могло декодировать его:
Обратите внимание, что, когда os.listdir () возвращает список строк, имена файлов, которые не могут декодироваться правильно, опущены вместо того, чтобы повысить UnicodeError.
Вопросительный знак является более или менее универсальным символом, отображенным, когда unicode символ не может быть представлен в определенном кодировании. Ваша терминальная или интерактивная сессия в соответствии с Windows, вероятно, использует ASCII или ISO-8859-1 или что-то. Таким образом, фактическая строка является unicode, но это переводится в???? при печати к терминалу. Вот почему это работает на PEZ, с помощью OSX.