LINUX.ORG.RU

Чем можно генерировать код вычисления выражения

 ,


0

2

Какие есть инструменты для генерации оптимального кода (на C например) вычисляющего выражение?

Выражение берется например как результат преобразований в maxima. Оно может быть длинным и содержать повторяющиеся подвыражения. И обычно оно является матрицей, в разных элементах которой тоже есть одинаковые подвыражения.

Или может быть есть смысл как-то исходно формировать выражение с учетом вычислительной эффективности. То есть надо начинать это делать еще в CAS.

★★

Выражение берется например как результат преобразований в maxima.

Вроде в maxima есть какая-то возможность генерировать код. Вроде как на Фортране. Видел что про это? Полагаю, что и на Common Lisp может.

Zubok ★★★★★
()

А разве хороший оптимизирующий компилятор не превратит неоптимальный код на С в оптимальный машинный код?

amomymous ★★★
()
Ответ на: комментарий от Zubok

Да действительно.

X : [id, iq, th, wR, M, E];
dF : [	(Ux*cos(th)+Uy*sin(th) - id*R + wR*iq*Lq) / Ld,
	(Uy*cos(th)-Ux*sin(th) - iq*R - wR*id*Ld - wR*E) / Lq,
	wR,
	Zp * (1.5*Zp*iq*(E - (Lq - Ld)*id) - M) / J,
	0,
	0];

F : X + dF * dT;

A : jacobian(F, X);

fortran(A);

Выдает.

      A(1,1) = 1-dT*R/Ld
      A(1,2) = Lq*dT*wR/Ld
      A(1,3) = (cos(th)*Uy-sin(th)*Ux)*dT/Ld
      A(1,4) = iq*Lq*dT/Ld
      A(1,5) = 0
      A(1,6) = 0
      A(2,1) = -Ld*dT*wR/Lq
      A(2,2) = 1-dT*R/Lq
      A(2,3) = (-sin(th)*Uy-cos(th)*Ux)*dT/Lq
      A(2,4) = dT*(-E-id*Ld)/Lq
      A(2,5) = 0
      A(2,6) = -dT*wR/Lq
      A(3,1) = 0
      A(3,2) = 0
      A(3,3) = 1
      A(3,4) = dT
      A(3,5) = 0
      A(3,6) = 0
      A(4,1) = 1.4999999999999997d+0*iq*(Ld-Lq)*Zp**2*dT/J
      A(4,2) = 1.4999999999999997d+0*Zp**2*dT*(E-id*(Lq-Ld))/J
      A(4,3) = 0
      A(4,4) = 1
      A(4,5) = -Zp*dT/J
      A(4,6) = 1.4999999999999997d+0*iq*Zp**2*dT/J
      A(5,1) = 0
      A(5,2) = 0
      A(5,3) = 0
      A(5,4) = 0
      A(5,5) = 1
      A(5,6) = 0
      A(6,1) = 0
      A(6,2) = 0
      A(6,3) = 0
      A(6,4) = 0
      A(6,5) = 0
      A(6,6) = 1

Но это не C и если сделать сначала optimize(A) то генератор зафейлится. Да и без оптимизации, если добавить умножение матриц, тоже вывод непригоден для использования (некорректный вывод длинных строк).

P : matrix(	[p0, p1, p3, p6, p10, p15],
		[p1, p2, p4, p7, p11, p16],
		[p3, p4, p5, p8, p12, p17],
		[p6, p7, p8, p9, p13, p18],
		[p10, p11, p12, p13, p14, p19],
		[p15, p16, p17, p18, p19, p20]);

Pk : A . P . transpose(A);

fortran(Pk);

Хотя вот optimize(Pk) выдает неплохой результат, на первый взгляд. Еще бы на C его транслировать.

amaora ★★
() автор топика
Последнее исправление: amaora (всего исправлений: 1)
Ответ на: комментарий от amomymous

Перемножение матриц в лоб тройным циклом вдруг развернет с учетом симметричности одной матрицы и разреженности другой? Где такие хорошие компиляторы?

amaora ★★
() автор топика

GSL и BLAS нужны тебе.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от amaora

Еще бы на C его транслировать.

f2c. Например, в OpenCASCADE куча математики была именно этим транслирована. http://en.wikipedia.org/wiki/F2c

С другой стороны, а чем Фортран плох? У математичков он в фаворе, компиляторы с него отличные. Эх, я писал на Фортране когда-то в универе.

И еще. Мне кажется, что я видел какие-то независимые трансляторы в фортран из maxima. Какие-то университетские разработки, что ли. Но точно не поручусь.

Zubok ★★★★★
()
Последнее исправление: Zubok (всего исправлений: 2)
Ответ на: комментарий от Zubok

f2c. Например, в OpenCASCADE куча математики была именно этим транслирована. http://en.wikipedia.org/wiki/F2c

Причем вроде он может компилировать при помощи f2c прямо внутри сишного проекта фортрановский код. Но я тонкостей не знаю. Просто слышал звон.

Zubok ★★★★★
()

Еще вроде Axiom в Fortran умеет. outputAsFortran(e)

Zubok ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.