1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Swift] 複素数型 Complex

Posted at

C#の複素数型は、↓こちらを参照ください。

Swift の記事ですが、今回の動作検証は Windows PC で行いました。

Intel N97 Processor, LPDDR5 RAM 12GB
Windows11 Pro 64bit 24H2 (26100.2161)
C# Compiler version 4.11.0-3.24460.3 (5649376e)
Swift version 5.9.2 (swift-5.9.2-RELEASE)

当初の Swift にはComplex型 はありませんでしたが、2019年12月にサポートされました。ただし、Complex型を使う場合は、Swift Numericsパッケージを追加する必要があります。

Package.swift(例)
import PackageDescription

let package = Package(
    name: "complex",
    dependencies: [
        .package(url: "https://github.com/apple/swift-numerics", from: "1.0.2")
    ],
    targets: [
        .executableTarget(
            name: "complex",
            dependencies: [
              .product(name: "Numerics", package: "swift-numerics")
            ]),
    ]
)

精度 C# vs Swift

冒頭の記事のコードを流用させていただきました。

C#
using System.Numerics;

Complex c = new Complex(0, 1);

Console.WriteLine(Complex.Multiply(c, c));
Console.WriteLine(Complex.Pow(c, 2));
Console.WriteLine(Complex.Sqrt(c));
Console.WriteLine(Complex.Pow(c, 0.5));
Console.WriteLine(Complex.Pow(c, c));
Swift
import Numerics

let c = Complex(0, 1)

print(c * c)
print(Complex.pow(c, 2))
print(Complex.sqrt(c))
print(Complex.pow(c, Complex(0.5, 0)))
print(Complex.pow(c, c))
C#結果
<-1; 0>
<-1; 1.2246467991473532E-16>
<0.7071067811865476; 0.7071067811865475>
<0.7071067811865476; 0.7071067811865476>
<0.20787957635076193; 0>
Swift結果
(-1.0, 0.0)
(-1.0, 1.2246467991473532e-16)
(0.7071067811865476, 0.7071067811865475)
(0.7071067811865476, 0.7071067811865475)
(0.20787957635076193, 0.0)

計算精度は、イーブンでした。

性能 C# vs Swift

冒頭の記事のマンデルブロ集合のコードを流用させていただきました。
10回描画の平均値(コンソール出力も含めた処理時間)

C#
using System.Numerics;
using System.Diagnostics;

long MandelbrotSet()
{
    Stopwatch sw = Stopwatch.StartNew();

    for (double y = -1.25d; y <= 1.25d; y += 2.5d / 24.0d)
    {
        for (double x = -2.0d; x <= 0.5d; x += 2.5d / 64.0d)
        {
            Complex z = new Complex(0, 0);
            Complex c = new Complex(x, y);
            for (int n = 0; n < 256; n++)
            {
                z = Complex.Pow(z, 2);
                z = Complex.Add(z, c);

                if (z.Magnitude > 2)
                {
                    Console.Write(".");
                    break;
                }
                if (n == 255)
                {
                    Console.Write("*");
                }
            }
        }
        Console.WriteLine("");
    }

    sw.Stop();
    return sw.ElapsedMilliseconds;
}

long total = 0;
List<long> results = new List<long>();
for (int n = 0; n < 10; n++)
{
    long result = MandelbrotSet();
    total += result;
    results.Add(result);
}

results.Sort();
foreach (var r in results)
{
    Console.WriteLine(r);
}
Console.WriteLine((double)total / (double)results.Count);
Swift
import Foundation
import Numerics

func MandelbrotSet() -> Double {
    let sw = Stopwatch.startNow()

    for y in stride(from: -1.25, through: 1.25, by: 2.5 / 24.0) {
        for x in stride(from: -2.0, through: 0.5, by: 2.5 / 64.0) {
            var z = Complex(0, 0)
            let c = Complex(x, y)
            for n in 0 ..< 256 {
                z = Complex.pow(z, 2)
                z += c
                
                if (z.magnitude > 2) {
                    print(".", terminator: "")
                    break
                }
                if (n == 255) {
                    print("*", terminator: "")
                }
            }
        }
        print()
    }

    sw.stop()
    return sw.elapsedMilliseconds
}


var total: Double = 0;
var results: [Double] = []
for _ in 0 ..< 10 {
    let result = MandelbrotSet()
    total += result
    results.append(result)
}

results.sort()
for r in results {
    print(r)
}
print(total / Double(results.count))
マンデルブロ集合
.................................................................
.................................................................
.................................................................
.................................................................
................................................*................
..............................................*****..............
..........................................*.*********.*..........
.......................................*********************.....
...................................*************************.....
..................................****************************...
......................********...*****************************...
....................************.****************************....
......*........*******************************************.......
....................************.****************************....
......................********...*****************************...
..................................****************************...
...................................*************************.....
.......................................*********************.....
..........................................*.*********.*..........
..............................................*****..............
................................................*................
.................................................................
.................................................................
.................................................................
.................................................................
C#結果
57
57
58
58
58
59
59
63
64
66
59.9
Swift結果
49.999237060546875
55.00030517578125
59.00001525878906
59.99946594238281
59.99946594238281
59.99946594238281
62.999725341796875
62.999725341796875
63.00163269042969
63.00163269042969
59.600067138671875

10回の平均値は 59.9ms と 59.6ms で、こちらもほぼイーブンです。(実行する度に、10〜20ミリ秒のブレがある)

どちらの結果もミリ秒単位ですが、C#は long型 、Swiftは Double型と違いがあります。そもそも正しいベンチマークになっていないのかも?



Swiftで使用した Stopwatch型はこちらを参照。

参考

実は、Complex型の何が便利なのか理解できていません。勉強不足ですみません。

古い記事ですが、ネットで見つけたサイトを紹介します。

  • 2016/7/13 (SwiftにまだComplex型が無かった頃)

  • 2019/11/12 (SwiftにComplex型がサポートされた後)

  • 日本語サイト




以上

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?