matlab中怎样计算一个矩阵中每个数的平方?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了matlab中怎样计算一个矩阵中每个数的平方?相关的知识,希望对你有一定的参考价值。

1、第一步我们首先需要知道求一个矩阵不同元素个数,需要用到unique函数,在命令行窗口中输入“help unique”,可以看到unique函数用法,

2、第二步输入a=[1 3 3 5;6 7 8 8;3 5 6 9],按回车键之后,创建一个3行4列的矩阵,

3、第三步输入unique(a),求a矩阵不同元素,

4、第四步按回车键之后,可以看到将a矩阵不同元素列出来了,形成了一个列向量

5、第五步输入length(unique(a)),求a矩阵不同元素的个数

参考技术A

1、我们首先需要知道matlab关于矩阵集合运算的一些函数,intersect函数求集合交集,setxor函数求集合不在交集中的元素。

2、我们打开matlab,在命令行窗口中输入help intersect,可以看到intersect函数的用法介绍,两个矩阵的交集就是相同的元素。

3、在命令行窗口中输入a=[1 2 3;4 5 6;7 8 9];b=[1 3 5;7 8 10;4 8 9],按回车键,新建a,b两个矩阵。

4、在命令行窗口中输入intersect(a,b),按回车键,可以得到a,b两个矩阵中相同的元素。

5、如果我们想得到两个矩阵中不相同的元素,可以使用setxor函数,在命令行窗口中help setxor,可以看到函数用法。

6、输入setxor(a,b)按回车键,可以得到a,b两个矩阵不相同的元素,也叫不在交集中的元素。

参考技术B 使用点运算。如果原矩阵式A,可以使用A.*A或者A.^2
MatLab中点运算是对相同维数的矩阵的对应元素进行相应的运算。
.* 点乘,相同维数的矩阵的对应元素相乘。
.^ 点乘幂,A.^B相同维数的矩阵A元素的B对应元素次幂。A.^n矩阵A中所有元素取n次幂。
.\ 点左除,相同维数的矩阵的对应元素进行\运算。
./ 点右除,相同维数的矩阵的对应元素进行/运算。
参考技术C 假设A是你说的矩阵,A.^2就是计算一个矩阵中每个数的平方

计算也是平方数的第 N 个三角数

【中文标题】计算也是平方数的第 N 个三角数【英文标题】:Computing Nth triangular number that is also a square number 【发布时间】:2015-03-28 14:51:50 【问题描述】:

这个问题是在练习比赛中出现的:

计算第 N 个三角数,它也是一个平方数,模 10006699。(1 ≤ N ≤ 10^18) 最多有 10^5 个测试案例。

我发现我可以很容易地用递归关系计算它 Ti = 6Ti-1 - Ti-2 sub> + 2,其中 T0 = 0T1 = 1。 p>

我使用矩阵求幂来获得每个测试用例大约 O(log N) 的性能,但它显然太慢了,因为有 10^5 个测试用例。事实上,即使约束只有 (1 ≤ N ≤ 10^6),这段代码也太慢了,我可以只进行 O(N) 预处理和 O(1) 查询。

我应该改变解决问题的方法,还是应该只优化代码的某些部分?

#include <ios>
#include <iostream>
#include <vector>
#define MOD 10006699

/*
Transformation Matrix:

 0 1 0   t[i]     t[i+1]
-1 6 1 * t[i+1] = t[i+2]
 0 0 1     2        2
*/

std::vector<std::vector<long long int> > multi(std::vector<std::vector<long long int> > a, std::vector<std::vector<long long int> > b)

    std::vector<std::vector<long long int> > c(3, std::vector<long long int>(3));
    for (int i = 0; i < 3; i++)
    
        for (int j = 0; j < 3; j++)
        
            for (int k = 0; k < 3; k++)
            
                c[i][j] += (a[i][k] * b[k][j]) % MOD;
                c[i][j] %= MOD;
            
        
    
    return c;


std::vector<std::vector<long long int> > power(std::vector<std::vector<long long int> > vec, long long int p)

    if (p == 1) return vec;
    else if (p % 2 == 1) return multi(vec, power(vec, p-1));
    else
    
        std::vector<std::vector<long long int> > x = power(vec, p/2);
        return multi(x, x);
    


int main()

    std::ios_base::sync_with_stdio(false);
    long long int n;
    while (std::cin >> n)
    
        if (n == 0) break;
        else
        
            std::vector<std::vector<long long int> > trans;
            long long int ans;
            trans.resize(3);

            trans[0].push_back(0);  
            trans[0].push_back(1);
            trans[0].push_back(0);
            trans[1].push_back(-1);
            trans[1].push_back(6);
            trans[1].push_back(1);
            trans[2].push_back(0);
            trans[2].push_back(0);
            trans[2].push_back(1);

            trans = power(trans, n);

            ans = (trans[0][1]%MOD + (2*trans[0][2])%MOD)%MOD;

            if (ans < 0) ans += MOD;

            std::cout << ans << std::endl;
        
    

【问题讨论】:

你能解释一下你是怎么得出这个公式的吗? 【参考方案1】:

注意:我删除了我的旧答案,这更有用

您似乎不太可能为该问题创建比 O(log N) 更好的渐近算法。但是,可以对您当前的代码进行一些修改,这不会改善渐近时间,但会提高性能

以下是对您的代码的修改,产生相同的答案:

#include <ctime>
#include <ios>
#include <iostream>
#include <vector>
#define MOD 10006699

void power(std::vector<std::vector<long long int> >& vec, long long int p)

    if (p == 1)
        return;

    else if (p & 1)
    
        std::vector<std::vector<long long int> > copy1 = vec;
        power(copy1, p-1);

        std::vector<std::vector<long long int> > copy2(3, std::vector<long long int>(3));
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
            
                for (int k = 0; k < 3; k++)
                    copy2[i][j] += (vec[i][k] * copy1[k][j]) % MOD;
                copy2[i][j] %= MOD;
            
        vec = copy2;

        return;
    

    else
    
        power(vec, p/2);

        std::vector<std::vector<long long int> > copy(3, std::vector<long long int>(3));
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
            
                for (int k = 0; k < 3; k++)
                    copy[i][j] += (vec[i][k] * vec[k][j]) % MOD;
                copy[i][j] %= MOD;
            
        vec = copy;

        return;
    


int main()

    std::ios_base::sync_with_stdio(false);
    long long int n;
    while (std::cin >> n)
    
        std::clock_t start = std::clock();
        if (n == 0) break;

        std::vector<std::vector<long long int> > trans;
        long long int ans;
        trans.resize(3);

        trans[0].push_back(0);  
        trans[0].push_back(1);
        trans[0].push_back(0);
        trans[1].push_back(-1);
        trans[1].push_back(6);
        trans[1].push_back(1);
        trans[2].push_back(0);
        trans[2].push_back(0);
        trans[2].push_back(1);

        power(trans, n);

        ans = (trans[0][1]%MOD + (2*trans[0][2])%MOD)%MOD;
        if (ans < 0) ans += MOD;
        std::cout << "Answer: " << ans << std::endl;

        std::cout << "Time: " << (std::clock() - start) / (double)(CLOCKS_PER_SEC / 1000) << " ms" << std::endl;
    

区别主要有:

c[i][j] %= MOD; 的代码运动在 k 循环之外 通过引用传递向量 更少的函数调用

如果我在 main 的 while 循环中放置与我在代码中相同的计时代码,请将文件命名为“before.cpp”,将文件命名为“after.cpp”,然后每次运行 10 次一个完整优化的行,那么这些是我的结果:

Alexanders-MBP:Desktop alexandersimes$ g++ before.cpp -O3 -o before
Alexanders-MBP:Desktop alexandersimes$ ./before 
1000000000000000000
Answer: 6635296
Time: 0.708 ms
1000000000000000000
Answer: 6635296
Time: 0.542 ms
1000000000000000000
Answer: 6635296
Time: 0.688 ms
1000000000000000000
Answer: 6635296
Time: 0.634 ms
1000000000000000000
Answer: 6635296
Time: 0.626 ms
1000000000000000000
Answer: 6635296
Time: 0.629 ms
1000000000000000000
Answer: 6635296
Time: 0.629 ms
1000000000000000000
Answer: 6635296
Time: 0.629 ms
1000000000000000000
Answer: 6635296
Time: 0.632 ms
1000000000000000000
Answer: 6635296
Time: 0.695 ms

Alexanders-MBP:Desktop alexandersimes$ g++ after.cpp -O3 -o after
Alexanders-MBP:Desktop alexandersimes$ ./after 
1000000000000000000
Answer: 6635296
Time: 0.283 ms
1000000000000000000
Answer: 6635296
Time: 0.287 ms
1000000000000000000
Answer: 6635296
Time: 0.27 ms
1000000000000000000
Answer: 6635296
Time: 0.27 ms
1000000000000000000
Answer: 6635296
Time: 0.266 ms
1000000000000000000
Answer: 6635296
Time: 0.265 ms
1000000000000000000
Answer: 6635296
Time: 0.266 ms
1000000000000000000
Answer: 6635296
Time: 0.267 ms
1000000000000000000
Answer: 6635296
Time: 0.21 ms
1000000000000000000
Answer: 6635296
Time: 0.208 ms

【讨论】:

除非他在 O(1) 中找到一种方法,否则我怀疑他的渐近性能会比 O(log N) 更好。但是,我将更改 while 循环时钟以包含 O(1) 操作,因为它们对小 N 有影响(编辑此人被指示删除了他的评论) 我无法编辑我的评论,因此删除了它,顺便说一句,这个建议不会对时间复杂度有任何改善,并且可能导致溢出问题,因为它不断添加到 c 而不应用 Mod 到它。 OP 说MOD10006699,这远不及溢出long long int(a[i][k] * b[k][j]) 可能会在通过模数之前溢出,但其中的 3 次加法不会溢出 long long int 将功率方法从递归更改为迭代并避免创建新的vector 可能会稍微改善这一点。有 27 个添加,但是是的,你是对的,这不会导致溢出。 @PhamTrung,你是对的,避免制作新的向量会产生很大的不同,我完全改变了我的代码并将其放在上面的答案中。此外,虽然有 27 次加法,但模数每 3 次迭代发生一次,这就是为什么我在溢出上下文中将其表述为 3 次加法

以上是关于matlab中怎样计算一个矩阵中每个数的平方?的主要内容,如果未能解决你的问题,请参考以下文章

matlab中怎样计算一个矩阵中每个数的平方?

matlab怎样求矩阵每一行的平方和?

matlab怎样求矩阵每一行的平方和?

怎样用matlab计算一个矩阵和大量矩阵分别相乘

Matlab中生成4阶魔方矩阵A,再分别计算A的数组平方和矩阵平方,给出执行语句以及计算结果

matlab中怎样求随机数的和、均方差、均值、平方