2023,江端さんの忘備録

「追い出し部屋」というものがあるそうです。

There is something called "kick-out rooms."

一つの部屋に集めて、何も仕事を与えない ―― ただし、給料は与え続ける

Gather them in one room and give them no work -- but keep paying them.

これによって、会社側は違法性を回避しつつ、社員を精神的に追い込んで解雇に追い込むことができる、ということのようです。

This room means that the company can avoid illegality, while at the same time psyching up the employee and forcing him or her into termination.

(最近は、このような企業の行為は、「違法行為」との司法判断がされているようです)

(Recently, there has been a judicial ruling that the actions of such companies are "illegal.")

-----

私も、若いころ、同じような目にあったことがあります。

I had a similar experience when I was younger.

「追い出し部屋」とはニュアンスが違いますが、事業部の炎上案件に巻き込まれて、長期派遣になったことがあります。

Although not quite as nuanced as "kick-out room," I have been on long-term assignment after getting caught up in a firestorm in a business unit.

いわば『炎上部屋』でしょうか

A "flame room," so to speak.

しかし、現場の主任からは『何もしないでくれ』と言われていました。

But the site chief told me, 'Don't do anything'.

私、この『何もしないでくれ』の意味を良く理解していました ―― つまるところ「政治」です。

I understood well what this 'do nothing' means -- after all, it is 'politics'.

現場は、人員を増員するということで、『一生懸命対応している』という演出が必要です。

The field needs to produce a 'hard-working response' in the form of increased staffing.

しかし、炎上している案件の中に、何も知らないエンジニアを突っ込むことは、とんでもないリスクでもあります。

However, it is also a tremendous risk to plunge an uninformed engineer into a project that is under fire.

なぜなら、ゼロから教育するコスト(時間、人員)がバカ高く、加えて、炎上案件の素人がシステムに触ることで、致命的な不具合を仕込みかねないからです。

This is because the cost (time, manpower) of training from scratch is ridiculously high, and in addition, amateurs on a flaming project can touch the system and plant fatal glitches.

それ故、この案件で必要だったのは、「何もしない人員」だったのです。

Hence, what was needed in this case was "do-nothing personnel.

-----

で、私が何をやっていたかというと、以前からやりたかったことを一人でやりまくっていました。

So what I was doing was something I had wanted to do for a long time in the flame room.

「Linuxのカーネル改造」です。

"Linux Kernel Modification"

この技術に手を出せる人はそれほど多くないと思います。(能力はさておき)膨大な時間が必要となるからです。

Not many people can afford this technology. (Let alone the ability to do so.) This is because it requires an enormous amount of time.

あの炎上部屋でのたった一人の静謐な時間は、今思い出しても、非常に贅沢な時間だったと思います。

The serenity of being alone in that flame room was a very luxurious time, as I recall now.

朝から晩まで好きなコーディングを月単位で貰えるような、そんな機会は滅多にあるものではありません。

It is not often that I get such an opportunity to get the coding I like from morning to night on a monthly basis.

そんでもって、ここで培った技で、その後10年はメシを喰ったという自覚があります。

And I am aware that the skills I developed here have kept me fed for the next 10 years.

-----

ソフトウェアエンジニアの強みは、「会社に命じられなくてもやれること(正確には「やりたいこと」)が山ほどあり、そして、それが『一人でもできる』」という点にあります。

The strength of software engineers lies in the fact that "there are a lot of things we can do (or more precisely, things we want to do) without being ordered by the company, and we can do them 'alone'.

そのような技は、自分のノウハウにもなり、上手くいけば、会社の利益にもなることもあります。

Such techniques can be your own know-how and, hopefully, benefit your company.

『楽しい「追い出し部屋」ライフ』という観点からも、プログラミング技術の取得はお勧めです。

From the viewpoint of "enjoyable 'kick-out room' life," acquiring programming skills is also recommended.

2023,江端さんの技術メモ

使う度に調べるので、メモしておきます。

1. 40歳から44歳の人の人数を数えろ
=COUNTIFS($B$1:$B$498, ">=45",$B$1:$B$498, "<50" )

2.55歳から59歳の人の不満値の平均値を求めよ
=AVERAGEIFS($J$1:$J$498, $B$1:$B$498, ">=55",$B$1:$B$498, "<60" )

Keywords: COUNTIF, COUNTIFS, AVERAGEIFS

 

2023,江端さんの忘備録

最近は聞かれなくなった言葉に、『自分探し』というものがあります。

One word that is no longer heard these days is "self-discovery.

―― 自分とは何者であるか

"Who I am"

哲学的な問いですが、私、この答を見つける最適最短手段を知っています。

This is a philosophical question, but I know the best and shortest way to find the answer.

『「育児」and/or「介護」の当事者になる』

Becoming a Party to "Childcare" and/or "Caregiving"

これだけです。

That's all.

-----

もう、そりゃ、自分が認識していなかった自分が「もろ見え」です。

I can already "see" myself that I didn't recognize.

特に、肉体的、精神的限界に至った時の、自分の中に潜む「どす黒い感情」が赤裸々に見えて ―― 自分でびっくりします。

Especially when I reach my physical and mental limits, I can see nakedly the "black emotions" that lurk within me -- I am surprised at myself.

『極限状態の戦場では、その人の本質が明らかになる』と言われます。

It is said that "the nature of a person is revealed on the battlefield under extreme conditions.

その意味で、「育児」「介護」は準戦場と言えるかもしれません。

"In this sense, "childcare" and "caregiving" could be described as a quasi-battlefield situation.

-----

もちろん、好んで戦場に行く必要はありません。

Of course, you do not have to go to the battlefield by preference.

これらを忌避して生きてもいいんですか ―― いいんです(楽天カードのCM風)。

Is it OK to live in evasion of these things? -- it's OK (Rakuten Card commercial style).

-----

ただ、個人的に言えば ―― 『「育児」and/or「介護」の当事者』になった人は「信用できる」とは思います。

However, speaking personally -- I think that people who have been "involved in "childcare" and/or "caregiving" are "trustworthy".

一方、このような「体験至上主義」が、いわゆる、結婚ハラスメント、育児ハラスメント、介護ハラスメントの温床になっている、という自覚もあります。

On the other hand, we are also aware that this "experience-history principle" has become a breeding ground for so-called marriage harassment, childcare harassment, and caregiver harassment.

2023,江端さんの忘備録

高校の時は、漠然と応用物理学を専攻したいと思っていました。

In high school, I vaguely wanted to major in applied physics.

大学では電子工学を、大学院では電気工学を、

I studied electronics in college and electrical engineering in graduate school.

そして、その後は、以下の図に記載した業務に携わり、

Then, afterwards, I was involved in the operations described in the following diagram.

で、本日、

So, the following card arrived today.

が、届きました。

-----

―― 思えば、遠くに来たもんだ

"Come to think of it, I've come a long way"

と、しみじみと実感しています。

I am deeply aware of this.

2023,江端さんの忘備録

今日も資料作成の為に、特許検索サイトに行きました。

I went to the patent search site again today to prepare documents.

ところが、

However,

というメッセージを受けて、今、困っています。

I am now in trouble because I received th above message.

メンテナンスは必須ですので、仕方がないことです。

Maintenance is a must, so it is inevitable.

しかし、『動いているのが当たり前と思っているものが止まる』というのは、困るものです。

However, it is troubling when 'things that we take for granted to be moving stop.

-----

そういえば、今回のコラムで、

In this column, I wrote

江端:「ああ、それは分かります。私たちは、普段から『私が突然いなくなっても、社会は1mmも困らない』ことを良く知っていますが、その事実を直視すると凹みますからね」

Ebata: "Oh, I understand that. We usually know very well that 'even if I suddenly disappear, society will not be troubled one millimeter,' but when we face that fact, it makes a dent, you know."

と記載しました。

で、今、

So, now, I am thinking

―― 私の価値って、特許検索エンジンの価値の1/1000以下よりも、はるかに低いんだろうなぁ

"I guess my value is much less than 1/1000th of the value of a patent search engine"

とか思って、勝手に凹んでいます。

And I am depressed on my own.

2023,江端さんの技術メモ

This program is based on the following page
https://qiita.com/ufoo68/items/9e4ca04578ba0f5fa5ff

This program solves the XOR problem using MLP with one hidden layer.

#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
//num of units
#define NUM_INPUT 2
//#define NUM_HIDDEN 20
#define NUM_HIDDEN 2

double sigmoid(double x) {
    return 1/(1+exp(-x));
}

//derivative of sigmoid function
double d_sigmoid(double x) {
    double a = 0.1;
    return a*x*(1-x);
}

int main(void) {
    srand((unsigned)time(NULL));
//train data
    double train_x[4][NUM_INPUT+1] = {{0, 0, -1},{0, 1, -1},{1, 0, -1},{1, 1, -1}};
    double d[4] = {0, 1, 1, 0};
//net
    double w[NUM_HIDDEN+1][NUM_INPUT+1];
    double v[NUM_HIDDEN+1];
    double y[4][NUM_HIDDEN+1];
    double z[4];
    double eta = 0.1;
    int epoch = 1000000;
//other
    int i, j, k, l;
    double tmp = 0;

//update weights using rand()
    for(l=0; l<NUM_HIDDEN+1; l++) {
        for(i=0; i<NUM_INPUT+1; i++) {
            w[l][i] = ((double)rand() / ((double)RAND_MAX + 1));
        }
    }
    for(i=0; i<NUM_HIDDEN+1; i++) {
        v[i] = ((double)rand() / ((double)RAND_MAX + 1));
    }

//tain
    for(k=0; k<epoch; k++) {
        //feedforward
        for(j=0; j<4; j++) {
            //hidden
            for(l=0; l<NUM_HIDDEN; l++) {
                for(i=0; i<NUM_INPUT+1; i++) {
                    tmp += train_x[j][i] * w[l][i];
                }
                y[j][l] = sigmoid(tmp);
                tmp = 0;
            }
            y[j][NUM_HIDDEN] = -1;
            //output
            for(i=0; i<NUM_HIDDEN+1; i++) {
                tmp += y[j][i] * v[i];
            }
            z[j] = sigmoid(tmp);
            tmp = 0;

        //backward
            //output
            for(i=0; i<NUM_HIDDEN+1; i++) {
                v[i] = v[i] - eta * y[j][i] * d_sigmoid(z[j]) * (z[j] - d[j]);
            }

            //hidden
            for(l=0; l<NUM_INPUT+1; l++) {
                for(i=0; i<NUM_HIDDEN+1; i++) {
                    w[i][l] = w[i][l] - eta * train_x[j][l] * d_sigmoid(y[j][i]) * d_sigmoid(z[j]) * (z[j] - d[j]) * v[i];
                }
            }
        }

		/*
        //print detail
        printf("z=");
        for(i=0; i<4; i++) {
            printf("%f ", z[i]);
        }
        printf("epoch:%d\n",k);
		*/
    }

//predict
    for(j=0; j<4; j++) {
        //hidden
        for(l=0; l<NUM_HIDDEN; l++) {
            for(i=0; i<NUM_INPUT+1; i++) {
                tmp += train_x[j][i] * w[l][i];
            }
            y[j][l] = sigmoid(tmp);
            tmp = 0;
        }
        y[j][NUM_HIDDEN] = -1;
        //output
        for(i=0; i<NUM_HIDDEN+1; i++) {
            tmp += y[j][i] * v[i];
        }
        z[j] = sigmoid(tmp);
        tmp = 0;
    }

//print result
    printf("z=");
    for(i=0; i<4; i++) {
        printf("%f ", z[i]);
    }
    printf("epoch:%d\n",k);


    for(i=0; i<NUM_INPUT+1; i++) {
        for(l=0; l<NUM_HIDDEN+1; l++) {
		  printf("w[%d][%d]:%f\n", i, l, w[i][l]);
        }
    }

    for(i=0; i<NUM_HIDDEN+1; i++) {
	  printf("v[%d]:%f\n",i, v[i]);
    }


    return 0;
}

Save this program as a name "mlp.c", compile ">gcc mlp.c" and execute ">./a.exe"

2023,江端さんの忘備録

本日は、コラムがリリースされましたので、お休みです。

Today's diary is taken off, as the new column has been released.

------

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━……‥‥・・・
連載記事アラート《アイティメディアID》 ………………………… 2023/02/25

Serial Article Alert 《Itimedia ID》 ........................ 2023/02/25

・・・‥‥……━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

「「お金に愛されないエンジニア」のための新行動論」の最新記事が掲載されました。

The latest article on "New Behavioral Theory for 'Engineers Not Loved by Money'" has been published.

■最新記事

- Latest Articles

1日1回の外出は2000円の価値? 「孤独」がもたらす損失を試算してみる

Is going out once a day worth 2,000 Yen? Let's estimate the loss that "loneliness" brings.

(イラストをクリックすると、記事に飛びます)

(Click on the figure to jump to the article)

今回は、「移動」と「ウェルビーイング」を解析した論文を読み解いてみました。

In this issue, I read a paper analyzing "mobility" and "wellbeing".

そこで得た結論は、「孤独を回避して幸せになりたいのなら、毎日外へ出ろ」というものです。

The conclusion I came to was, "If you want to avoid loneliness and be happy, go outside every day".

2023,江端さんの忘備録

こちらにも記載しましたが、3月に、大学生の学生の講義のコマを3つ持つ旨、担当指導教授から指示を受けました。

私の業務経歴は、「成果」ではなくて「怒り」で記載可能のようです。

In March, I have been instructed by my supervisor to have three lecture sessions for university students.

各種のネタは持っているのですが、まあ、最近なら『"AI"がウケがいいだろう』と思って、その旨を教授に返事をしました。

I had a variety of ideas, but I thought, well, "'AI' would be popular these days," I replied to the professor.

―― で、今、講義の準備に頭を抱えています。

Now, the "preparation for lectures" is giving me a headache.

-----

講義だけなら、1時間程度くらい、デタラメな英語をしゃべる続けることはできると思うのです。

I think I can keep speaking bullshit English for about an hour of the lecture.

その訓練は、20年前に完了しています。

That training was completed 20 years ago.

問題は「練習問題」です。

The problem is "practice problems".

AIというのは、基本的には『コンピュータプログラムを使った、暴力的な力まかせの計算の強行』です。

AI is basically 'violent forced computation' using computer programs.

―― プログラミングを知らない学生に、「座学」で「手計算」で「計算用紙」を使って、AIの計算プロセスを練習させる

"How to have students who do not know programming practice the AI calculation process in a "classroom" setting, using "hand calculations" and "calculation paper"

これが、想像を絶するほど難しいのです。

This is unimaginably difficult.

正直、どこから手をつけたら良いのか分からない、という感じです。

Frankly, I don't know where to start.

加えて、『講義の時間がわずか1時間』という制約が、私を苦しめています。

In addition, the restriction of 'only one hour of lecture time' has been a pain for me.

例えば、ベイズ推論、ファジィ推論、それぞれのAI技術の解説に、最低「5時間」は欲しいのですが、現状、それぞれ15分しかありません。

For example, I would like at least "5 hours" to explain the AI techniques of Bayesian and fuzzy reasoning, but currently I have only 15 minutes each.

このまま講義に突入すれば、『想像を絶するほど、つまらない講義になるだろう』と予感しています。

I have a feeling that if I go into the lecture as it is, 'it will be the most boring lecture imaginable'.

という訳で、ここ数日、ずっと頭を抱え続けています。

This is why I have been keeping my head in the sand for the past few days.

-----

「数学教育が、なぜ、あれほどつまらないものになるか」の断片を、理解したような気がします。

I think I understand a piece of "why math education can be so boring".

ここに至って、私は『数学教育を楽しいものにするには、少なくとも、今のコマの5~10倍以上の時間が必要だ』ということに、気がつきました。

It was here that I came to the realization that 'to make math education fun, we need at least five to ten times as much time as we have in our current frames.

2023,江端さんの技術メモ

Golang 文字列を数値に変換する方法で、文字列→実数なら、これが一番てっとり早そう

dest_lat, err := strconv.ParseFloat(row[2], 64)

strconv.ParseIntstrconv.ParseUnitは、文字列を解析して整数型を返す関数
それぞれ符号付き整数型と符号なし整数型に対応している。

 

2023,江端さんの技術メモ

I hope you could understand the min-max method of Fuzzy reasoning, using the following Go programming list.

package main

import (
	"fmt"
	"os"
)

func max_2(a, b float64) float64 {
	if a > b {
		return a
	} else {
		return b
	}
}

func min_2(a, b float64) float64 {
	if a > b {
		return b
	} else {
		return a
	}
}

type condition_MF3 struct { // Base class for condition_MF3
	center  float64
	width   float64
	express string
}

func new_condition_MF3(_center, _width float64, _express string) *condition_MF3 {
	c3 := new(condition_MF3)
	c3.center = _center
	c3.width = _width
	c3.express = _express
	return c3
}

// Class for the membership function (3 mountains) of the former case
func (c3 *condition_MF3) func_X(_x float64) float64 {
		// x,y denote coordinates on the membership function
	x := _x
	y := 0.0 // The value of y is always greater than or equal to 0 and less than or equal to 1

	if c3.express == "LESS" {
		if x <= c3.center-c3.width {
			y = 1.0
		} else if x <= c3.center {
			y = -1.0 / c3.width * (x - c3.center)
		} else {
			y = 0.0
		}
	} else if c3.express == "COMMON" {
		if x <= c3.center-c3.width {
			y = 0.0
		} else if x <= c3.center {
			y = 1.0/c3.width*(x-c3.center) + 1.0
		} else if x <= c3.center+c3.width {
			y = -1.0/c3.width*(x-c3.center) + 1.0
		} else {
			y = 0.0
		}
	} else if c3.express == "MORE" {
		if x <= c3.center {
			y = 0.0
		} else if x <= c3.center+c3.width {
			y = 1.0 / c3.width * (x - c3.center)
		} else {
			y = 1.0
		}
	} else {
		fmt.Println("MF3: wrong expression")
		os.Exit(1)
	}
	return y
}

type condition_MF5 struct { // Base class for condition_MF5
	center  float64
	width   float64
	express string
}

func new_condition_MF5(_center, _width float64, _express string) *condition_MF5 {
	c5 := new(condition_MF5)
	c5.center = _center
	c5.width = _width
	c5.express = _express
	return c5
}

func (c5 *condition_MF5) func_X(_x float64) float64 {
	// Class for the former membership function (5 mountains)
	// x,y are the coordinates on the membership function

	x := _x
	y := 0.0 // The value of y is always greater than or equal to 0 and less than or equal to 1

	if c5.express == "LESSLESS" {
		if x <= c5.center-2.0*c5.width {
			y = 1.0
		} else if x <= c5.center-c5.width {
			y = -1.0/c5.width*(x-(c5.center-2.0*c5.width)) + 1.0
		} else {
			y = 0.0
		}
	} else if c5.express == "LESS" {
		if x <= c5.center-2.0*c5.width {
			y = 0.0
		} else if x <= c5.center-c5.width {
			y = 1.0/c5.width*(x-(c5.center-c5.width)) + 1.0
		} else if x <= c5.center {
			y = -1.0/c5.width*(x-(c5.center-c5.width)) + 1.0
		} else {
			y = 0.0
		}
	} else if c5.express == "COMMON" {
		if x <= c5.center-c5.width {
			y = 0.0
		} else if x <= c5.center {
			y = 1.0/c5.width*(x-c5.center) + 1.0
		} else if x <= c5.center+c5.width {
			y = -1.0/c5.width*(x-c5.center) + 1.0
		} else {
			y = 0.0
		}
	} else if c5.express == "MORE" {
		if x <= c5.center {
			y = 0.0
		} else if x <= c5.center+c5.width {
			y = 1.0/c5.width*(x-(c5.center+c5.width)) + 1.0
		} else if x <= c5.center+2.0*c5.width {
			y = -1.0/c5.width*(x-(c5.center+c5.width)) + 1.0
		} else {
			y = 0.0
		}
	} else if c5.express == "MOREMORE" {
		if x <= c5.center+c5.width {
			y = 0.0
		} else if x <= c5.center+2.0*c5.width {
			y = 1.0/c5.width*(x-(c5.center+2.0*c5.width)) + 1.0
		} else {
			y = 1.0
		}
	} else {
		fmt.Println("MF5 func_X(): wrong expression")
		os.Exit(1)
	}

	return y
}

/////////////////////////////

type action_MF5 struct { // Base class for action_MF5
	center  float64
	width   float64
	express string
	x       float64
	y       float64
}

type action_MF3 struct { // Base class for action_MF3
	center  float64
	width   float64
	express string
	x       float64
	y       float64
}


func new_action_MF5(_center, _width float64, _express string) *action_MF5 {
	a5 := new(action_MF5)
	a5.center = _center
	a5.width = _width
	a5.express = _express

	if a5.express == "LESSLESS" {
		a5.x = a5.center - 2.0*a5.width
	} else if a5.express == "LESS" {
		a5.x = a5.center - a5.width
	} else if a5.express == "COMMON" {
		a5.x = a5.center
	} else if a5.express == "MORE" {
		a5.x = a5.center + a5.width
	} else if a5.express == "MOREMORE" {
		a5.x = a5.center + 2.0*a5.width
	} else {
		fmt.Println("new_action_MF5: wrong scale expression")
		os.Exit(-1)
	}

	a5.y = 0.0

	return a5
}

func new_action_MF3(_center, _width float64, _express string) *action_MF3 {
	a3 := new(action_MF3)
	a3.center = _center
	a3.width = _width
	a3.express = _express

	if a3.express == "LESS" {
		a3.x = a3.center - a3.width
	} else if a3.express == "COMMON" {
		a3.x = a3.center
	} else if a3.express == "MORE" {
		a3.x = a3.center + a3.width
	} else {
		fmt.Println("new_action_MF3: wrong scale expression")
		os.Exit(-1)
	}

	a3.y = 0.0

	return a3
}


// The latter membership function (5 mountains) class
func (a5 *action_MF5) func_Y() float64 {
	return a5.y
}

// The latter membership function (3 mountains) class
func (a3 *action_MF3) func_Y() float64 {
	return a3.y
}

func (a5 *action_MF5) func_Max(b float64) {
	a5.y = max_2(b, a5.y)
}


func (a3 *action_MF3) func_Max(b float64) {
	a3.y = max_2(b, a3.y)
}


func (a5 *action_MF5) func_X() float64 {
	return a5.x
}

func (a3 *action_MF3) func_X() float64 {
	return a3.x
}


func fuzzy_reasoning(temp, humi float64) float64 {

	// Temperature(former)
	Temp_Less := new_condition_MF3(20, 10, "LESS")
	Temp_Common := new_condition_MF3(20, 10, "COMMON")
	Temp_More := new_condition_MF3(20, 10, "MORE")

	// Humidity(former)
	Humi_Less := new_condition_MF3(50, 20, "LESS")
	Humi_Common := new_condition_MF3(50, 20, "COMMON")
	Humi_More := new_condition_MF3(50, 20, "MORE")

	// Switch(前件部)
	Switch_Less := new_action_MF3(0,1,"LESS")
	Switch_Common := new_action_MF3(0,1,"COMMON")
	Switch_More := new_action_MF3(0,1,"MORE")

	// [Rule 01] 
	Rule01 := min_2(Temp_More.func_X(temp), Humi_More.func_X(humi))
	Switch_Less.func_Max(Rule01) // the latters values are overwritten if the value is large enough.
	fmt.Println("Rule01", Rule01)

	// [Rule 02] 
	Rule02 := min_2(Temp_Common.func_X(temp), Humi_More.func_X(humi))
	Switch_Common.func_Max(Rule02) // the latters values are overwritten if the value is large enough.
	fmt.Println("Rule02", Rule02)

	// [Rule 03] 
	Rule03 := min_2(Temp_More.func_X(temp), Humi_Common.func_X(humi))
	Switch_Less.func_Max(Rule03) // the latters values are overwritten if the value is large enough.
	fmt.Println("Rule03", Rule03)

	// [Rule 04] 
	Rule04 := min_2(Temp_Less.func_X(temp), Humi_Less.func_X(humi))
	Switch_More.func_Max(Rule04) // the latters values are overwritten if the value is large enough.
	fmt.Println("Rule04", Rule04)


	// Reasoning calculations
	numerator :=
			Switch_Less.func_X()*Switch_Less.func_Y() +
			Switch_Common.func_X()*Switch_Common.func_Y() +
			Switch_More.func_X()*Switch_More.func_Y() 

	denominator :=
			Switch_Less.func_Y() +
			Switch_Common.func_Y() +
			Switch_More.func_Y() 


	reasoning := numerator / denominator

	return reasoning

}

func main(){

	 fmt.Println(fuzzy_reasoning(27.0, 67.0))
}