Даны натуральное число p и вещественные квадратные матрицы A,B,C размером 4х4 . Получить (A*B*C)^p , используя функцию Mult(A,B) возвращающую результат умножения двух матриц.
Язык – Борланд С++
Я вроде со всем разобралась кроме возведения в степень , помогите доделать программу)
Вот мой текст:
#include <iostream.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
void mult(double *a,double *b,double *q)
{
int i,j,k;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
for(k=0;k<4;k++)
*(q+4*i+j)=*(q+4*i+j)+(*(a+4*i+k))*(*(b+4*k+j));
}
void main()
{
clrscr();
double A[4][4],B[4][4],D[4][4],C[4][4],L[4][4] ;
int i,j,k,l,n,m;
randomize();
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
A[i][j]=random(10);
D[i][j]=0;
cout <<" "<<A[i][j];
}cout<<endl;
}
cout<<" "<<endl;
for(k=0;k<4;k++)
{
for(l=0;l<4;l++)
{
B[k][l]=random(10);
cout<<" "<<B[k][l];
}cout<<endl;
}
mult(A[0],B[0],D[0]);
cout<<"matrica D[4][4]=A[4][4]*B[4][4] :"<<endl;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
cout<<""<<D[i][j]<<endl;
//cout <<D[4][4];//
for(n=0;n<4;n++)
{
for(m=0;m<4;m++)
{
C[n][m]=random(10);
L[i][j]=0;
cout<<""<<C[n][m];
}cout<<endl;
}
cout<<" "<<endl;
mult(D[0],C[0],L[0]);
cout<<"matrica L[4][4]=C[4][4]*D[4][4] :"<<endl;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
cout<<""<<L[i][j]<<endl;
getch();
}
3 июля 2008 в 7:01
Мне, почему-то, тоже пришла в голову такая мысль… ещё вчера
2 июля 2008 в 23:01
peace
на самом деле, я полагаю, Юлечка уже месяц как сдала свою программу
2 июля 2008 в 5:02
Оптимизация — вещь хорошая. А вдруг скорость важна? Почему я не могу посоветовать? А потом Юля пусть сама решает, пользоваться ей моим советом или нет.
1 июля 2008 в 22:01
вот и я про то же. зачем усложнять жизнь студентам оптимизациями, которые с них не спрашивают?
1 июля 2008 в 9:02
По условию число натуральное. Зачем усложнять себе жизнь? К тому же можно, если захотеть, алгоритм доработать с учётом вещественного показателя. Главное, я идею привёл с оптимизацией. А от неё уже можно плясать куда хош. Кроме того, для заданного условия этой идеи полностью достаточно.
1 июля 2008 в 8:05
конечно бывает. например извлечение квадратного корня: какую матрицу нужно умножить саму на себя, чтобы получить данную?
1 июля 2008 в 7:05
А такое бывает разве? А кроме того, разве до меня в этой теме кто-нибудь предлагал алгоритм такой с нецелой степенью? Покажите мен пальчиком где, а то я сам что-то не нашёл… :-/
1 июля 2008 в 0:03
а как насчет возведения матрицы в нецелую степень?
30 июня 2008 в 14:03
Быстрое возведение в целую степень
double pow(double b, int d)
{
double r=1;
while (d>0)
{
if (d&1) {r*=b;–d} else {d>>=1;b*=b}
}
return r;
}
Вместо double пишешь свой матричный тип, и умножения заменяешь.
Если тупо d раз умножать, трудоёмкость=d*(сложность умножения матриц), а при быстрой степени — log(d)*(сложность умножения матриц).
30 июня 2008 в 14:03
Естественно, для отрицательных d нужно делать отдельную ветку с нахождением обратной матрицы.
24 мая 2008 в 11:02
Эмм… Вы, наверное, не знаете, что делает операция сложения указателя и числа. На sizeof() умножать не надо.
24 мая 2008 в 8:04
не уверен, что в функции mult конструкция
*(q+4*i+j)=*(q+4*i+j)+(*(a+4*i+k))*(*(b+4*k+j));
будет работать вообще.
правильный вариант выглядит примерно так:
*(q+(4*i+j)*sizeof(*q))=*(q+(4*i+j)*sizeof(*q))+(*(a+(4*i+k)*sizeof(*a)))*(*(b+(4*k+j)*sizeof(*b)));
а лучше как-нибудь так:
q[4*i+j]=q[4*i+j]+a[4*i+k]*b[4*k+j];
что, впрочем, как и принятие функцией многомерных массивов типа a[4][4], усложняет последующую поддержку кода.
20 мая 2008 в 10:02
1) Я бы написал обнуление в функции mult, да и получала бы она не "double *a" а "doube a[4][4]", тогда можно было бы писать "a[i][j]" вместо "*(a+i*4+j)", и вызывалась бы как "mult(A,B,D)" вместо "mult(A[0],B[0],D[0])"
2) Возведение в степень можно написать за O(logp) уможений матриц:
double L[4][4]; // это то, что уже подсчитано
double R[4][4]; // То, куда будем собирать ответ
double T[4][4]; // Временная
// сначала запишем в R единичнуюю матрицу
for (i=0;i<4;i++) for (j=0;j<4;j++)
R[i][j] = i == j ? 1 : 0;
// Теперь умножаем
for (; p > 0; p /= 2)
{
if (p % 2 == 1)
{
mult(L, R, T);
memcpy(R, T, sizeof(R));
}
// Возводим L в квадрат
mult(L, L, T);
memcpy(L, T, sizeof(R));
}
20 мая 2008 в 9:02
Как-то жОстко ты с массивами и функциями работаешь… Ну, да не суть.
Делаешь цикл от 1 до p и в нём вызываешь свою чудо-"функцию" mult:
for(i=1; i<p; i++)
{
mult(L[0],temp[0], result[0]);
temp = result;
}
result – твой искомый результат.