2021年3月28日 星期日

如何在Linux上加密IronPython Script

1. 首先編寫要加密的模組(e.g. test.py),模組當中內容可為函數或物件,如圖一。

2. 在Linux當中,需加入mono指令配合ipy64.exe來執行pyc.py以加密模組檔test.py最後輸出test.dll到個人home目錄底下,如圖二。

3. 撰寫工具tool.py檔,透過clr引用test.dll檔案。注意tool.py是不加密的,如圖三。

4. 在AEDT當中測試tool.py,如圖四。

(圖一) 在test.py模組定義函式myadd()

(圖二) 加密test.py 並輸出 test.dll

(圖三) clr匯入test.dll模組,並使用test模組當中的myadd()函式

(圖四) 執行測試無誤





2021年3月13日 星期六

如何用命令列啟動script?

本範例可以用bat檔啟動視窗,視窗可以保持在最上層,但是又可以操作AEDT環境。兩者可以平行操作。不像之前的toolkit會鎖定AEDT環境。總共有三個檔案,以下為程式範例:

run.bat

SET PATH=C:\Program Files\AnsysEM\AnsysEM20.2\Win64\common\IronPython\
ipy64 test.py
pause

test.xaml
<Window 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Template Window" Height="144.165" Width="300" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" Background="#FFEAEBFF" Topmost="True">
<Grid>
<Button Content="Execute" HorizontalAlignment="Right" Height="36" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="93" Click="Button_Click"/>
<TextBox x:Name="input_tb" HorizontalAlignment="Right" Height="27" Margin="0,10,10,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="214" VerticalContentAlignment="Center"/>
<Label Content="Value:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="55"/>
</Grid>
</Window>

test.py
# coding=UTF-8
import os, sys, re, clr, json, math, cmath

# 初始化環境,設定win64_path
win64_path = 'C:/Program Files/AnsysEM/AnsysEM20.2/Win64'
sys.path.append(win64_path)
sys.path.append(win64_path + '/PythonFiles/DesktopPlugin/')
sys.path.append(win64_path + '/common/IronPython/DLLs')

import ScriptEnv

ScriptEnv.Initialize("Ansoft.ElectronicsDesktop")
from Ansys.Ansoft.CoreCOMScripting.Util import COMUtil

# 初始化WPF視窗環境
clr.AddReference('IronPython.Wpf')
clr.AddReference('System.Drawing')
clr.AddReference('System.Windows.Forms')
import wpf
from System.Windows import Window
from System.Windows.Forms import OpenFileDialog, SaveFileDialog, FolderBrowserDialog, DialogResult

# 程式主體放在try段落當中,
try:
oProject = oDesktop.GetActiveProject()
oDesign = oProject.GetActiveDesign()
oEditor = oDesign.SetActiveEditor("3D Modeler")


def AddWarningMessage(info):
oDesktop.AddMessage(oProject.GetName(), oDesign.GetName(), 1, info)


class MyWindow(Window):
def __init__(self):
wpf.LoadComponent(self, 'test.xaml')
oDesktop.ClearMessages("", "", 2)

def Button_Click(self, sender, e):
AddWarningMessage(self.input_tb.Text)


MyWindow().ShowDialog()
except:
raise

# 程式執行成功與否,都能釋放AEDT專案
finally:
COMUtil.PInvokeProxyAPI.ReleaseCOMObjectScope(0)

(圖一)程式執行跳出視窗,同時仍能設定AEDT


2021年3月7日 星期日

奇異值分解(SVD, Singular Value Decomposition)

SVD是一個很有趣的技術。以下A為100x4矩陣,共400筆數值。做完SVD分解之後,可以拆成U:100x100, sigma:100x4, VT矩陣:4x4,乍看數量反而暴增(400 -> 10416)。然而只需保留矩陣的一小部分,(本範例四個奇異值只保留兩個來簡化矩陣,U1:100x2, sigma1:2x2, VT1:2x4,總數212),之後就可以透過矩陣乘法還原出原始的400筆數值,等於儲存資料量少了近一半(212/400=53%)。

SVD用在資料壓縮,機器學習等領域。網路上可以找到許多關於SVD的解說。。各位可以比較還原後的A1矩陣與A矩陣幾乎完全相同。SVD運算有點複雜,所幸Scipy已經提供了現成的函式可以使用。

# -*- coding: utf-8 -*-
"""
Created on Sun Mar 7 08:29:34 2021

@author: mlin
"""
import numpy as np
from numpy import linalg as la
A=np.array([[i+0,i+1,i+2, i+3] for i in range(100)])

#A矩陣(100x4)做奇異值分解分成三矩陣相乘
U,sigma,VT=la.svd(A)

#U(100x100)sigma(100x4),V(4x4)

print('_'*40)
U1 = U[:,:2]
#U1(100x2)

sigma1 = np.array([[sigma[0],0],[0, sigma[1]]])
#sigma1(2x2)

VT1 = VT[:2,:]
#VT1(2x4)

A1 = np.dot(np.dot(U1,sigma1), VT1)

2021年3月1日 星期一

使用優化來找出目標方程式最小值

參考https://www.youtube.com/watch?v=cXHvC_FGx24

目標方程式為四元(x1, x2, x3, x4)非線性方程式x1*x4*(x1+x2+x3)+x3。有兩條約束式,變數範圍1到5。求解滿足約束方程式的目標方程式最大值。

代碼:

# -*- coding: utf-8 -*-
import numpy as np
from scipy.optimize import minimize

def objective(x):
x1, x2, x3, x4 = x
return x1*x4*(x1+x2+x3)+x3

def constraint1(x):
x1, x2, x3, x4 = x
return x1*x2*x3*x4-25

def constraint2(x):
x1, x2, x3, x4 = x
return 40 - x1**2 - x2**2 - x3**2 - x4**2

bnds = ((1, 5), (1, 5), (1, 5), (1, 5))

con1 = {'type':'ineq', 'fun':constraint1}
con2 = {'type':'eq', 'fun':constraint2}

x0 = [1, 5, 5, 1]
sol = minimize(objective, x0, bounds = bnds, constraints=[con1, con2], tol=1e-6, options = {'maxiter':100, 'disp':True})
print(sol)

(圖一)優化結果

其中 x1, x3, x3, x4 = [1. , 4.7429961 , 3.82115462, 1.37940765],
最小值為17.01401724563517